aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml18
-rw-r--r--runtime/doc/eval.txt18
-rw-r--r--runtime/doc/msgpack_rpc.txt5
-rw-r--r--src/nvim/CMakeLists.txt1
-rw-r--r--src/nvim/api/ui.c2
-rw-r--r--src/nvim/edit.c1
-rw-r--r--src/nvim/eval.c59
-rw-r--r--src/nvim/eval.h8
-rw-r--r--src/nvim/ex_cmds2.c2
-rw-r--r--src/nvim/ex_docmd.c3
-rw-r--r--src/nvim/globals.h24
-rw-r--r--src/nvim/hashtab.c3
-rw-r--r--src/nvim/main.c2
-rw-r--r--src/nvim/mbyte.c18
-rw-r--r--src/nvim/message.c19
-rw-r--r--src/nvim/msgpack_rpc/helpers.c6
-rw-r--r--src/nvim/os/shell.c4
-rw-r--r--src/nvim/rbuffer.c4
-rw-r--r--src/nvim/screen.c8
-rw-r--r--src/nvim/shada.c4
-rw-r--r--src/nvim/syntax.c4
-rw-r--r--src/nvim/testdir/Makefile1
-rw-r--r--src/nvim/testdir/runtest.vim14
-rw-r--r--src/nvim/testdir/test_alot.vim1
-rw-r--r--src/nvim/testdir/test_expr.vim29
-rw-r--r--src/nvim/testdir/test_expr_utf8.vim1
-rw-r--r--src/nvim/testdir/test_regexp_utf8.vim1
-rw-r--r--src/nvim/testdir/test_viml.vim8
-rw-r--r--src/nvim/testdir/test_visual.vim1
-rw-r--r--src/nvim/tui/tui.c4
-rw-r--r--src/nvim/ui.c15
-rw-r--r--src/nvim/version.c28
-rw-r--r--src/nvim/vim.h8
-rw-r--r--test/functional/core/exit_spec.lua46
-rw-r--r--test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua12
-rw-r--r--test/functional/legacy/060_exists_and_has_functions_spec.lua16
-rw-r--r--test/functional/legacy/packadd_spec.lua7
-rw-r--r--test/functional/ui/screen.lua9
-rw-r--r--test/functional/ui/screen_basic_spec.lua114
39 files changed, 404 insertions, 124 deletions
diff --git a/.travis.yml b/.travis.yml
index 1437f7e25b..039a00cce8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,9 +9,7 @@ env:
# http://docs.travis-ci.com/user/speeding-up-the-build/#Paralellizing-your-build-on-one-VM
- MAKE_CMD="make -j2"
# Update PATH for pip.
- - PATH="$(python2.7 -c 'import site; print(site.getuserbase())')/bin:$PATH"
- # LLVM symbolizer path.
- - LLVM_SYMBOLIZER="$(which llvm-symbolizer-3.4)"
+ - PATH="$(python2.7 -c 'import site; print(site.getuserbase())')/bin:/usr/lib/llvm-symbolizer-3.8/bin:$PATH"
# Build directory for Neovim.
- BUILD_DIR="$TRAVIS_BUILD_DIR/build"
# Build directory for third-party dependencies.
@@ -36,9 +34,8 @@ env:
-DCMAKE_TOOLCHAIN_FILE=$TRAVIS_BUILD_DIR/cmake/i386-linux-gnu.toolchain.cmake"
# Environment variables for Clang sanitizers.
- ASAN_OPTIONS="detect_leaks=1:check_initialization_order=1:log_path=$LOG_DIR/asan"
- - ASAN_SYMBOLIZER_PATH="$LLVM_SYMBOLIZER"
- - TSAN_OPTIONS="external_symbolizer_path=$LLVM_SYMBOLIZER log_path=$LOG_DIR/tsan"
- - UBSAN_OPTIONS="log_path=$LOG_DIR/ubsan"
+ - TSAN_OPTIONS="log_path=$LOG_DIR/tsan"
+ - UBSAN_OPTIONS="print_stacktrace=1 log_path=$LOG_DIR/ubsan"
# Environment variables for Valgrind.
- VALGRIND_LOG="$LOG_DIR/valgrind-%p.log"
# Cache marker for third-party dependencies cache.
@@ -70,10 +67,10 @@ matrix:
compiler: gcc-5 -m32
env: BUILD_32BIT=ON
- os: linux
- compiler: clang
+ compiler: clang-3.8
env: CLANG_SANITIZER=ASAN_UBSAN
- os: linux
- compiler: clang
+ compiler: clang-3.8
env: CLANG_SANITIZER=TSAN
- os: osx
compiler: clang
@@ -96,11 +93,12 @@ addons:
# TODO: Remove PPA when Travis gets Python >=3.3.
- deadsnakes
- ubuntu-toolchain-r-test
+ - llvm-toolchain-precise-3.8
packages:
- autoconf
- automake
- build-essential
- - clang-3.4
+ - clang-3.8
- cmake
- g++-5-multilib
- g++-multilib
@@ -109,7 +107,7 @@ addons:
- gdb
- libc6-dev-i386
- libtool
- - llvm-3.4-dev
+ - llvm-3.8-dev
- pkg-config
- python3.3-dev
- unzip
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 9c6cbd5a1a..cca53db531 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1383,6 +1383,9 @@ v:dying Normally zero. When a deadly signal is caught it's set to
< Note: if another deadly signal is caught when v:dying is one,
VimLeave autocommands will not be executed.
+ *v:exiting* *exiting-variable*
+v:exiting The exit value Nvim will use. Before exiting, it is |v:null|.
+
*v:errmsg* *errmsg-variable*
v:errmsg Last given error message. It's allowed to set this variable.
Example: >
@@ -1718,6 +1721,21 @@ v:swapcommand Normal mode command to be executed after a file has been
example, when jumping to a tag the value is ":tag tagname\r".
For ":edit +cmd file" the value is ":cmd\r".
+ *v:t_TYPE* *v:t_bool* *t_bool-varialble*
+v:t_bool Value of Boolean type. Read-only. See: |type()|
+ *v:t_dict* *t_dict-varialble*
+v:t_dict Value of Dictionary type. Read-only. See: |type()|
+ *v:t_float* *t_float-varialble*
+v:t_float Value of Float type. Read-only. See: |type()|
+ *v:t_func* *t_func-varialble*
+v:t_func Value of Funcref type. Read-only. See: |type()|
+ *v:t_list* *t_list-varialble*
+v:t_list Value of List type. Read-only. See: |type()|
+ *v:t_number* *t_number-varialble*
+v:t_number Value of Number type. Read-only. See: |type()|
+ *v:t_string* *t_string-varialble*
+v:t_string Value of String type. Read-only. See: |type()|
+
*v:termresponse* *termresponse-variable*
v:termresponse The escape sequence returned by the terminal for the |t_RV|
termcap entry. It is set when Vim receives an escape sequence
diff --git a/runtime/doc/msgpack_rpc.txt b/runtime/doc/msgpack_rpc.txt
index 757f5574d4..c074eb43ff 100644
--- a/runtime/doc/msgpack_rpc.txt
+++ b/runtime/doc/msgpack_rpc.txt
@@ -390,8 +390,9 @@ of update.
The menu mappings changed.
["mode_change", mode]
- The mode changed. Currently sent when "insert", "replace" and "normal"
- modes are entered. A client could for instance change the cursor shape.
+ The mode changed. Currently sent when "insert", "replace", "cmdline" and
+ "normal" modes are entered. A client could for instance change the cursor
+ shape.
["popupmenu_show", items, selected, row, col]
When `popupmenu_external` is set to true, nvim will not draw the
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 49edfda838..f2b75dca2a 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -326,6 +326,7 @@ elseif(CLANG_TSAN)
message(STATUS "Enabling Clang thread sanitizer for nvim.")
set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-DEXITFREE ")
set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-fsanitize=thread ")
+ set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-fPIE ")
set_property(TARGET nvim APPEND_STRING PROPERTY LINK_FLAGS "-fsanitize=thread ")
endif()
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index 56b41f1eea..9178538110 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -271,6 +271,8 @@ static void remote_ui_mode_change(UI *ui, int mode)
ADD(args, STRING_OBJ(cstr_to_string("insert")));
} else if (mode == REPLACE) {
ADD(args, STRING_OBJ(cstr_to_string("replace")));
+ } else if (mode == CMDLINE) {
+ ADD(args, STRING_OBJ(cstr_to_string("cmdline")));
} else {
assert(mode == NORMAL);
ADD(args, STRING_OBJ(cstr_to_string("normal")));
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index dcb772e23c..9d07878f24 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -2322,7 +2322,6 @@ static int ins_compl_make_cyclic(void)
return count;
}
-
// Set variables that store noselect and noinsert behavior from the
// 'completeopt' value.
void completeopt_was_set(void)
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 750ef4f94f..8e8d36b442 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -387,6 +387,14 @@ static struct vimvar {
VV(VV__NULL_LIST, "_null_list", VAR_LIST, VV_RO),
VV(VV__NULL_DICT, "_null_dict", VAR_DICT, VV_RO),
VV(VV_VIM_DID_ENTER, "vim_did_enter", VAR_NUMBER, VV_RO),
+ VV(VV_TYPE_NUMBER, "t_number", VAR_NUMBER, VV_RO),
+ VV(VV_TYPE_STRING, "t_string", VAR_NUMBER, VV_RO),
+ VV(VV_TYPE_FUNC, "t_func", VAR_NUMBER, VV_RO),
+ VV(VV_TYPE_LIST, "t_list", VAR_NUMBER, VV_RO),
+ VV(VV_TYPE_DICT, "t_dict", VAR_NUMBER, VV_RO),
+ VV(VV_TYPE_FLOAT, "t_float", VAR_NUMBER, VV_RO),
+ VV(VV_TYPE_BOOL, "t_bool", VAR_NUMBER, VV_RO),
+ VV(VV_EXITING, "exiting", VAR_NUMBER, VV_RO),
};
#undef VV
@@ -400,7 +408,7 @@ static struct vimvar {
#define vv_dict vv_di.di_tv.vval.v_dict
#define vv_tv vv_di.di_tv
-static dictitem_T vimvars_var; /* variable used for v: */
+static dictitem_T vimvars_var; // variable used for v:
#define vimvarht vimvardict.dv_hashtab
typedef struct {
@@ -562,10 +570,19 @@ void eval_init(void)
set_vim_var_list(VV_ERRORS, list_alloc());
set_vim_var_nr(VV_SEARCHFORWARD, 1L);
set_vim_var_nr(VV_HLSEARCH, 1L);
+ set_vim_var_nr(VV_COUNT1, 1);
+ set_vim_var_nr(VV_TYPE_NUMBER, VAR_TYPE_NUMBER);
+ set_vim_var_nr(VV_TYPE_STRING, VAR_TYPE_STRING);
+ set_vim_var_nr(VV_TYPE_FUNC, VAR_TYPE_FUNC);
+ set_vim_var_nr(VV_TYPE_LIST, VAR_TYPE_LIST);
+ set_vim_var_nr(VV_TYPE_DICT, VAR_TYPE_DICT);
+ set_vim_var_nr(VV_TYPE_FLOAT, VAR_TYPE_FLOAT);
+ set_vim_var_nr(VV_TYPE_BOOL, VAR_TYPE_BOOL);
set_vim_var_special(VV_FALSE, kSpecialVarFalse);
set_vim_var_special(VV_TRUE, kSpecialVarTrue);
set_vim_var_special(VV_NULL, kSpecialVarNull);
+ set_vim_var_special(VV_EXITING, kSpecialVarNull);
set_reg_var(0); // default for v:register is not 0 but '"'
}
@@ -2145,11 +2162,9 @@ get_lval (
if (lp->ll_tv->v_type == VAR_DICT) {
if (len == -1) {
- /* "[key]": get key from "var1" */
- key = get_tv_string(&var1); /* is number or string */
- if (*key == NUL) {
- if (!quiet)
- EMSG(_(e_emptykey));
+ // "[key]": get key from "var1"
+ key = get_tv_string_chk(&var1); // is number or string
+ if (key == NULL) {
clear_tv(&var1);
return NULL;
}
@@ -4600,10 +4615,8 @@ eval_index (
dictitem_T *item;
if (len == -1) {
- key = get_tv_string(&var1);
- if (*key == NUL) {
- if (verbose)
- EMSG(_(e_emptykey));
+ key = get_tv_string_chk(&var1);
+ if (key == NULL) {
clear_tv(&var1);
return FAIL;
}
@@ -6587,10 +6600,8 @@ static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate)
}
if (evaluate) {
key = get_tv_string_buf_chk(&tvkey, buf);
- if (key == NULL || *key == NUL) {
- /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */
- if (key != NULL)
- EMSG(_(e_emptykey));
+ if (key == NULL) {
+ // "key" is NULL when get_tv_string_buf_chk() gave an errmsg
clear_tv(&tvkey);
goto failret;
}
@@ -10658,7 +10669,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (!n) {
if (STRNICMP(name, "patch", 5) == 0) {
if (name[5] == '-'
- && strlen(name) > 11
+ && strlen(name) >= 11
&& ascii_isdigit(name[6])
&& ascii_isdigit(name[8])
&& ascii_isdigit(name[10])) {
@@ -16800,17 +16811,17 @@ static void f_type(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int n = -1;
switch (argvars[0].v_type) {
- case VAR_NUMBER: n = 0; break;
- case VAR_STRING: n = 1; break;
- case VAR_FUNC: n = 2; break;
- case VAR_LIST: n = 3; break;
- case VAR_DICT: n = 4; break;
- case VAR_FLOAT: n = 5; break;
+ case VAR_NUMBER: n = VAR_TYPE_NUMBER; break;
+ case VAR_STRING: n = VAR_TYPE_STRING; break;
+ case VAR_FUNC: n = VAR_TYPE_FUNC; break;
+ case VAR_LIST: n = VAR_TYPE_LIST; break;
+ case VAR_DICT: n = VAR_TYPE_DICT; break;
+ case VAR_FLOAT: n = VAR_TYPE_FLOAT; break;
case VAR_SPECIAL: {
switch (argvars[0].vval.v_special) {
case kSpecialVarTrue:
case kSpecialVarFalse: {
- n = 6;
+ n = VAR_TYPE_BOOL;
break;
}
case kSpecialVarNull: {
@@ -17754,6 +17765,8 @@ void set_vcount(long count, long count1, int set_prevcount)
/// @param[in] val Value to set to.
void set_vim_var_nr(const VimVarIndex idx, const varnumber_T val)
{
+ clear_tv(&vimvars[idx].vv_tv);
+ vimvars[idx].vv_type = VAR_NUMBER;
vimvars[idx].vv_nr = val;
}
@@ -17763,6 +17776,8 @@ void set_vim_var_nr(const VimVarIndex idx, const varnumber_T val)
/// @param[in] val Value to set to.
void set_vim_var_special(const VimVarIndex idx, const SpecialVarValue val)
{
+ clear_tv(&vimvars[idx].vv_tv);
+ vimvars[idx].vv_type = VAR_SPECIAL;
vimvars[idx].vv_special = val;
}
diff --git a/src/nvim/eval.h b/src/nvim/eval.h
index 1061840816..630e309442 100644
--- a/src/nvim/eval.h
+++ b/src/nvim/eval.h
@@ -127,6 +127,14 @@ typedef enum {
VV__NULL_LIST, // List with NULL value. For test purposes only.
VV__NULL_DICT, // Dictionary with NULL value. For test purposes only.
VV_VIM_DID_ENTER,
+ VV_TYPE_NUMBER,
+ VV_TYPE_STRING,
+ VV_TYPE_FUNC,
+ VV_TYPE_LIST,
+ VV_TYPE_DICT,
+ VV_TYPE_FLOAT,
+ VV_TYPE_BOOL,
+ VV_EXITING,
} VimVarIndex;
/// All recognized msgpack types
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index f68663c60c..3b92b3734a 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -2552,7 +2552,7 @@ static void add_pack_plugin(char_u *fname, void *cookie)
}
if (cookie != &APP_ADD_DIR) {
- static const char *plugpat = "%s/plugin/*.vim"; // NOLINT
+ static const char *plugpat = "%s/plugin/**/*.vim"; // NOLINT
static const char *ftpat = "%s/ftdetect/*.vim"; // NOLINT
size_t len = STRLEN(ffname) + STRLEN(ftpat);
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 76dddf874d..23b1a50fc8 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -7970,7 +7970,8 @@ static void ex_startinsert(exarg_T *eap)
static void ex_stopinsert(exarg_T *eap)
{
restart_edit = 0;
- stop_insert_mode = TRUE;
+ stop_insert_mode = true;
+ clearmode();
}
/*
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 301a2c1663..f81fb43eaf 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -788,8 +788,28 @@ EXTERN int vr_lines_changed INIT(= 0); /* #Lines changed by "gR" so far */
/// Encoding used when 'fencs' is set to "default"
EXTERN char_u *fenc_default INIT(= NULL);
-// To speed up BYTELEN() we keep a table with the byte lengths for utf-8
-EXTERN char utf8len_tab[256];
+// To speed up BYTELEN(); keep a lookup table to quickly get the length in
+// bytes of a UTF-8 character from the first byte of a UTF-8 string. Bytes
+// which are illegal when used as the first byte have a 1. The NUL byte has
+// length 1.
+EXTERN char utf8len_tab[256] INIT(= {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1,
+});
# if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
/* Pointers to functions and variables to be loaded at runtime */
diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c
index 7d4ae61fc4..fa4077f22f 100644
--- a/src/nvim/hashtab.c
+++ b/src/nvim/hashtab.c
@@ -368,8 +368,7 @@ hash_T hash_hash(char_u *key)
hash_T hash = *key;
if (hash == 0) {
- // Empty keys are not allowed, but we don't want to crash if we get one.
- return (hash_T) 0;
+ return (hash_T)0;
}
// A simplistic algorithm that appears to do very well.
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 1bd622bdba..9b9976ac0a 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -557,6 +557,8 @@ void getout(int exitval)
if (exmode_active)
exitval += ex_exitval;
+ set_vim_var_nr(VV_EXITING, exitval);
+
/* Position the cursor on the last screen line, below all the text */
ui_cursor_goto((int)Rows - 1, 0);
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 7be0be7106..2ecd86974e 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -69,24 +69,6 @@ struct interval {
#endif
/*
- * Lookup table to quickly get the length in bytes of a UTF-8 character from
- * the first byte of a UTF-8 string.
- * Bytes which are illegal when used as the first byte have a 1.
- * The NUL byte has length 1.
- */
-char utf8len_tab[256] =
-{
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1,
-};
-
-/*
* Like utf8len_tab above, but using a zero for illegal lead bytes.
*/
static uint8_t utf8len_tab_zero[256] =
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 1de2347b12..f9cfc49197 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -19,6 +19,7 @@
#include "nvim/fileio.h"
#include "nvim/func_attr.h"
#include "nvim/getchar.h"
+#include "nvim/main.h"
#include "nvim/mbyte.h"
#include "nvim/memory.h"
#include "nvim/misc1.h"
@@ -581,6 +582,24 @@ bool emsgf(const char *const fmt, ...)
return emsg(IObuff);
}
+static void msg_emsgf_event(void **argv)
+{
+ char *s = argv[0];
+ (void)emsg((char_u *)s);
+ xfree(s);
+}
+
+void msg_schedule_emsgf(const char *const fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vim_vsnprintf((char *)IObuff, IOSIZE, fmt, ap, NULL);
+ va_end(ap);
+
+ char *s = xstrdup((char *)IObuff);
+ loop_schedule(&main_loop, event_create(1, msg_emsgf_event, 1, s));
+}
+
/*
* Like msg(), but truncate to a single line if p_shm contains 't', or when
* "force" is TRUE. This truncates in another way as for normal messages.
diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c
index c3a909692f..5137b375f0 100644
--- a/src/nvim/msgpack_rpc/helpers.c
+++ b/src/nvim/msgpack_rpc/helpers.c
@@ -125,7 +125,7 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
dest = conv(((String) { \
.size = obj->via.attr.size, \
.data = (obj->via.attr.ptr == NULL || obj->via.attr.size == 0 \
- ? NULL \
+ ? xmemdupz("", 0) \
: xmemdupz(obj->via.attr.ptr, obj->via.attr.size)), \
})); \
break; \
@@ -326,7 +326,9 @@ void msgpack_rpc_from_string(String result, msgpack_packer *res)
FUNC_ATTR_NONNULL_ARG(2)
{
msgpack_pack_str(res, result.size);
- msgpack_pack_str_body(res, result.data, result.size);
+ if (result.size > 0) {
+ msgpack_pack_str_body(res, result.data, result.size);
+ }
}
typedef struct {
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index 18ee008d66..9e6effd21b 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -548,8 +548,8 @@ static void shell_write_cb(Stream *stream, void *data, int status)
if (status) {
// Can happen if system() tries to send input to a shell command that was
// backgrounded (:call system("cat - &", "foo")). #3529 #5241
- EMSG2(_("E5677: Error writing input to shell-command: %s"),
- uv_err_name(status));
+ msg_schedule_emsgf(_("E5677: Error writing input to shell-command: %s"),
+ uv_err_name(status));
}
if (stream->closed) { // Process may have exited before this write.
ELOG("stream was already closed");
diff --git a/src/nvim/rbuffer.c b/src/nvim/rbuffer.c
index a2cc432eca..111af0d0fb 100644
--- a/src/nvim/rbuffer.c
+++ b/src/nvim/rbuffer.c
@@ -18,7 +18,7 @@ RBuffer *rbuffer_new(size_t capacity)
capacity = 0x10000;
}
- RBuffer *rv = xmalloc(sizeof(RBuffer) + capacity);
+ RBuffer *rv = xcalloc(1, sizeof(RBuffer) + capacity);
rv->full_cb = rv->nonfull_cb = NULL;
rv->data = NULL;
rv->size = 0;
@@ -78,7 +78,7 @@ void rbuffer_reset(RBuffer *buf) FUNC_ATTR_NONNULL_ALL
size_t temp_size;
if ((temp_size = rbuffer_size(buf))) {
if (buf->temp == NULL) {
- buf->temp = xmalloc(rbuffer_capacity(buf));
+ buf->temp = xcalloc(1, rbuffer_capacity(buf));
}
rbuffer_read(buf, buf->temp, buf->size);
}
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 591f781e0e..a851cd5ed1 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -6827,12 +6827,18 @@ void unshowmode(bool force)
if (!redrawing() || (!force && char_avail() && !KeyTyped)) {
redraw_cmdline = true; // delete mode later
} else {
+ clearmode();
+ }
+}
+
+// Clear the mode message.
+void clearmode(void)
+{
msg_pos_mode();
if (Recording) {
recording_mode(hl_attr(HLF_CM));
}
msg_clr_eos();
- }
}
static void recording_mode(int attr)
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index 01c0807d82..d902079739 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -1575,7 +1575,9 @@ static char *shada_filename(const char *file)
do { \
const String s_ = (s); \
msgpack_pack_bin(spacker, s_.size); \
- msgpack_pack_bin_body(spacker, s_.data, s_.size); \
+ if (s_.size > 0) { \
+ msgpack_pack_bin_body(spacker, s_.data, s_.size); \
+ } \
} while (0)
/// Write single ShaDa entry
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index e57965ac2c..cd37bde3cb 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -392,7 +392,9 @@ void syntax_start(win_T *wp, linenr_T lnum)
* Also do this when a change was made, the current state may be invalid
* then.
*/
- if (syn_block != wp->w_s || changedtick != syn_buf->b_changedtick) {
+ if (syn_block != wp->w_s
+ || syn_buf != wp->w_buffer
+ || changedtick != syn_buf->b_changedtick) {
invalidate_current_state();
syn_buf = wp->w_buffer;
syn_block = wp->w_s;
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index 67e7c97905..c6e9c26c57 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -32,6 +32,7 @@ SCRIPTS := \
# Keep test_alot*.res as the last one, sort the others.
NEW_TESTS = \
test_cscope.res \
+ test_cmdline.res \
test_hardcopy.res \
test_help_tagjump.res \
test_history.res \
diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim
index e2d1e67a22..d1857565a4 100644
--- a/src/nvim/testdir/runtest.vim
+++ b/src/nvim/testdir/runtest.vim
@@ -42,6 +42,14 @@ endif
" This also enables use of line continuation.
set viminfo+=nviminfo
+" Use utf-8 or latin1 be default, instead of whatever the system default
+" happens to be. Individual tests can overrule this at the top of the file.
+if has('multi_byte')
+ set encoding=utf-8
+else
+ set encoding=latin1
+endif
+
" Avoid stopping at the "hit enter" prompt
set nomore
@@ -51,6 +59,9 @@ lang mess C
" Always use forward slashes.
set shellslash
+" Make sure $HOME does not get read or written.
+let $HOME = '/does/not/exist'
+
function RunTheTest(test)
echo 'Executing ' . a:test
if exists("*SetUp")
@@ -123,6 +134,9 @@ for s:test in sort(s:tests)
endfor
+" Don't write viminfo on exit.
+set viminfo=
+
if s:fail == 0
" Success, create the .res file so that make knows it's done.
exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
index dacea81a34..d75430ed8d 100644
--- a/src/nvim/testdir/test_alot.vim
+++ b/src/nvim/testdir/test_alot.vim
@@ -8,7 +8,6 @@ source test_ex_undo.vim
source test_expr.vim
source test_expr_utf8.vim
source test_feedkeys.vim
-source test_cmdline.vim
source test_menu.vim
source test_options.vim
source test_popup.vim
diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim
index 7ea4ebc7df..66a10b05e1 100644
--- a/src/nvim/testdir/test_expr.vim
+++ b/src/nvim/testdir/test_expr.vim
@@ -1,5 +1,20 @@
" Tests for expressions.
+func Test_version()
+ call assert_true(has('patch-7.4.001'))
+ call assert_true(has('patch-7.4.01'))
+ call assert_true(has('patch-7.4.1'))
+ call assert_true(has('patch-6.9.999'))
+ call assert_true(has('patch-7.1.999'))
+ call assert_true(has('patch-7.4.123'))
+
+ call assert_false(has('patch-7'))
+ call assert_false(has('patch-7.4'))
+ call assert_false(has('patch-7.4.'))
+ call assert_false(has('patch-9.1.0'))
+ call assert_false(has('patch-9.9.1'))
+endfunc
+
func Test_strgetchar()
call assert_equal(char2nr('a'), strgetchar('axb', 0))
call assert_equal(char2nr('x'), strgetchar('axb', 1))
@@ -23,3 +38,17 @@ func Test_strcharpart()
call assert_equal('a', strcharpart('axb', -1, 2))
endfunc
+
+func Test_dict()
+ let d = {'': 'empty', 'a': 'a', 0: 'zero'}
+ call assert_equal('empty', d[''])
+ call assert_equal('a', d['a'])
+ call assert_equal('zero', d[0])
+ call assert_true(has_key(d, ''))
+ call assert_true(has_key(d, 'a'))
+
+ let d[''] = 'none'
+ let d['a'] = 'aaa'
+ call assert_equal('none', d[''])
+ call assert_equal('aaa', d['a'])
+endfunc
diff --git a/src/nvim/testdir/test_expr_utf8.vim b/src/nvim/testdir/test_expr_utf8.vim
index 7bdcb4f65f..9ea6d8872b 100644
--- a/src/nvim/testdir/test_expr_utf8.vim
+++ b/src/nvim/testdir/test_expr_utf8.vim
@@ -2,7 +2,6 @@
if !has('multi_byte')
finish
endif
-scriptencoding utf-8
func Test_strgetchar_utf8()
call assert_equal(char2nr('á'), strgetchar('áxb', 0))
diff --git a/src/nvim/testdir/test_regexp_utf8.vim b/src/nvim/testdir/test_regexp_utf8.vim
index 38f9ed41d5..ecb03a0f8c 100644
--- a/src/nvim/testdir/test_regexp_utf8.vim
+++ b/src/nvim/testdir/test_regexp_utf8.vim
@@ -1,5 +1,4 @@
" Tests for regexp in utf8 encoding
-scriptencoding utf-8
func s:equivalence_test()
let str = "AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐẔ aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑẕ"
diff --git a/src/nvim/testdir/test_viml.vim b/src/nvim/testdir/test_viml.vim
index c39c5e6b28..a11d62f5cf 100644
--- a/src/nvim/testdir/test_viml.vim
+++ b/src/nvim/testdir/test_viml.vim
@@ -949,6 +949,14 @@ func Test_type()
call assert_equal(6, type(v:false))
call assert_equal(6, type(v:true))
call assert_equal(7, type(v:null))
+ call assert_equal(v:t_number, type(0))
+ call assert_equal(v:t_string, type(""))
+ call assert_equal(v:t_func, type(function("tr")))
+ call assert_equal(v:t_list, type([]))
+ call assert_equal(v:t_dict, type({}))
+ call assert_equal(v:t_float, type(0.0))
+ call assert_equal(v:t_bool, type(v:false))
+ call assert_equal(v:t_bool, type(v:true))
endfunc
"-------------------------------------------------------------------------------
diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim
index 83bae967e2..cf0e535937 100644
--- a/src/nvim/testdir/test_visual.vim
+++ b/src/nvim/testdir/test_visual.vim
@@ -2,7 +2,6 @@
if !has('multi_byte')
finish
endif
-scriptencoding utf-8
if !has('visual')
finish
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 5e30517c5a..2171e580ba 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -461,6 +461,10 @@ static void tui_mode_change(UI *ui, int mode)
if (data->showing_mode != INSERT) {
unibi_out(ui, data->unibi_ext.set_cursor_shape_bar);
}
+ } else if (mode == CMDLINE) {
+ if (data->showing_mode != CMDLINE) {
+ unibi_out(ui, data->unibi_ext.set_cursor_shape_bar);
+ }
} else if (mode == REPLACE) {
if (data->showing_mode != REPLACE) {
unibi_out(ui, data->unibi_ext.set_cursor_shape_ul);
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index eb500414a7..ea0bccb1cd 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -177,14 +177,14 @@ void ui_refresh(void)
pum_set_external(pum_external);
}
-static void ui_refresh_handler(void **argv)
+static void ui_refresh_event(void **argv)
{
ui_refresh();
}
void ui_schedule_refresh(void)
{
- loop_schedule(&main_loop, event_create(1, ui_refresh_handler, 0));
+ loop_schedule(&main_loop, event_create(1, ui_refresh_event, 0));
}
void ui_resize(int new_width, int new_height)
@@ -532,13 +532,16 @@ static void ui_mode_change(void)
if (!full_screen) {
return;
}
- /* Get a simple UI mode out of State. */
- if ((State & REPLACE) == REPLACE)
+ // Get a simple UI mode out of State.
+ if ((State & REPLACE) == REPLACE) {
mode = REPLACE;
- else if (State & INSERT)
+ } else if (State & INSERT) {
mode = INSERT;
- else
+ } else if (State & CMDLINE) {
+ mode = CMDLINE;
+ } else {
mode = NORMAL;
+ }
UI_CALL(mode_change, mode);
conceal_check_cursur_line();
}
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 47967ebc9a..e9bd1b7438 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -131,7 +131,7 @@ static int included_patches[] = {
// 2314,
// 2313,
2312,
- // 2311,
+ // 2311 NA
// 2310 NA
2309,
// 2308 NA
@@ -356,7 +356,7 @@ static int included_patches[] = {
// 2089 NA
// 2088,
// 2087,
- // 2086,
+ 2086,
// 2085,
// 2084,
// 2083,
@@ -371,7 +371,7 @@ static int included_patches[] = {
// 2074,
// 2073,
// 2072,
- // 2071,
+ 2071,
// 2070 NA
// 2069,
// 2068,
@@ -435,7 +435,7 @@ static int included_patches[] = {
// 2010,
// 2009,
// 2008,
- // 2007,
+ 2007,
// 2006,
// 2005,
// 2004 NA
@@ -514,12 +514,12 @@ static int included_patches[] = {
// 1931 NA
// 1930 NA
// 1929 NA
- // 1928,
+ 1928,
// 1927 NA
// 1926 NA
// 1925 NA
// 1924 NA
- // 1923,
+ 1923,
// 1922 NA
// 1921 NA
// 1920 NA
@@ -734,31 +734,31 @@ static int included_patches[] = {
// 1713 NA
1712,
1711,
- // 1710,
+ // 1710 NA
// 1709 NA
// 1708,
- // 1707,
+ 1707,
// 1706 NA
// 1705 NA
1704,
1703,
// 1702,
- // 1701,
+ 1701,
1700,
- // 1699,
+ 1699,
// 1698 NA
1697,
- // 1696,
+ 1696,
1695,
// 1694 NA
// 1693 NA
// 1692,
- // 1691,
+ 1691,
// 1690 NA
// 1689 NA
// 1688 NA
// 1687 NA
- // 1686,
+ 1686,
// 1685,
// 1684 NA
// 1683 NA
@@ -784,7 +784,7 @@ static int included_patches[] = {
1663,
// 1662 NA
// 1661 NA
- // 1660,
+ 1660,
// 1659 NA
1658,
// 1657 NA
diff --git a/src/nvim/vim.h b/src/nvim/vim.h
index 32eba55c18..8271abda8d 100644
--- a/src/nvim/vim.h
+++ b/src/nvim/vim.h
@@ -123,6 +123,14 @@ Error: configure did not run properly.Check auto/config.log.
#define FAIL 0
#define NOTDONE 2 /* not OK or FAIL but skipped */
+// Type values for type().
+#define VAR_TYPE_NUMBER 0
+#define VAR_TYPE_STRING 1
+#define VAR_TYPE_FUNC 2
+#define VAR_TYPE_LIST 3
+#define VAR_TYPE_DICT 4
+#define VAR_TYPE_FLOAT 5
+#define VAR_TYPE_BOOL 6
/*
* values for xp_context when doing command line completion
diff --git a/test/functional/core/exit_spec.lua b/test/functional/core/exit_spec.lua
new file mode 100644
index 0000000000..3fb39f3e78
--- /dev/null
+++ b/test/functional/core/exit_spec.lua
@@ -0,0 +1,46 @@
+local helpers = require('test.functional.helpers')(after_each)
+
+local command = helpers.command
+local eval = helpers.eval
+local eq, neq = helpers.eq, helpers.neq
+local run = helpers.run
+
+describe('v:exiting', function()
+ local cid
+
+ before_each(function()
+ helpers.clear()
+ cid = helpers.nvim('get_api_info')[1]
+ end)
+
+ it('defaults to v:null', function()
+ eq(1, eval('v:exiting is v:null'))
+ end)
+
+ it('is 0 on normal exit', function()
+ local function on_setup()
+ command('autocmd VimLeavePre * call rpcrequest('..cid..', "")')
+ command('autocmd VimLeave * call rpcrequest('..cid..', "")')
+ command('quit')
+ end
+ local function on_request()
+ eq(0, eval('v:exiting'))
+ return ''
+ end
+ run(on_request, nil, on_setup)
+ end)
+
+ it('is non-zero after :cquit', function()
+ local function on_setup()
+ command('autocmd VimLeavePre * call rpcrequest('..cid..', "")')
+ command('autocmd VimLeave * call rpcrequest('..cid..', "")')
+ command('cquit')
+ end
+ local function on_request()
+ neq(0, eval('v:exiting'))
+ return ''
+ end
+ run(on_request, nil, on_setup)
+ end)
+
+end)
diff --git a/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua b/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
index 4189e8a33a..c6883e4902 100644
--- a/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
+++ b/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
@@ -28,8 +28,6 @@ local function run_test_with_regexpengine(regexpengine)
e y
f z
g a啷bb
- h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐẔ
- i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑẕ
j 0123❤x
k combinations
l ä ö ü ᾱ̆́]])
@@ -68,14 +66,6 @@ local function run_test_with_regexpengine(regexpengine)
feed([[/\%U12345678<cr>x]])
feed([[/[\U1234abcd\u1234\uabcd]<cr>x]])
feed([[/\%d21879b<cr>x]])
- feed('/ [[=A=]]* [[=B=]]* [[=C=]]* [[=D=]]* [[=E=]]* [[=F=]]* ' ..
- '[[=G=]]* [[=H=]]* [[=I=]]* [[=J=]]* [[=K=]]* [[=L=]]* [[=M=]]* ' ..
- '[[=N=]]* [[=O=]]* [[=P=]]* [[=Q=]]* [[=R=]]* [[=S=]]* [[=T=]]* ' ..
- '[[=U=]]* [[=V=]]* [[=W=]]* [[=X=]]* [[=Y=]]* [[=Z=]]*/e<cr>x')
- feed('/ [[=a=]]* [[=b=]]* [[=c=]]* [[=d=]]* [[=e=]]* [[=f=]]* ' ..
- '[[=g=]]* [[=h=]]* [[=i=]]* [[=j=]]* [[=k=]]* [[=l=]]* [[=m=]]* ' ..
- '[[=n=]]* [[=o=]]* [[=p=]]* [[=q=]]* [[=r=]]* [[=s=]]* [[=t=]]* ' ..
- '[[=u=]]* [[=v=]]* [[=w=]]* [[=x=]]* [[=y=]]* [[=z=]]*/e<cr>x')
-- Line j. Test backwards search from a multi-byte character.
feed('/x<cr>x')
@@ -125,8 +115,6 @@ local function run_test_with_regexpengine(regexpengine)
e y
f z
g abb
- h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐ
- i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑ
j 012❤
k œ̄ṣ́m̥̄ᾱ̆́
l ä ö ü ᾱ̆́
diff --git a/test/functional/legacy/060_exists_and_has_functions_spec.lua b/test/functional/legacy/060_exists_and_has_functions_spec.lua
index cbd857c524..3e99f6df57 100644
--- a/test/functional/legacy/060_exists_and_has_functions_spec.lua
+++ b/test/functional/legacy/060_exists_and_has_functions_spec.lua
@@ -638,15 +638,6 @@ describe('exists() and has() functions', function()
call TestExists()
- function TestHas()
- redir >> test.out
- for pl in ['6.9.999', '7.1.999', '7.4.123', '9.1.0', '9.9.1']
- echo 'has patch ' . pl . ': ' . has('patch-' . pl)
- endfor
- redir END
- endfunc
- call TestHas()
-
edit! test.out
set ff=unix
]=])
@@ -858,12 +849,7 @@ describe('exists() and has() functions', function()
OK
g:footest#x = 1
footest#F() 0
- UndefFun() 0
- has patch 6.9.999: 1
- has patch 7.1.999: 1
- has patch 7.4.123: 1
- has patch 9.1.0: 0
- has patch 9.9.1: 0]])
+ UndefFun() 0]])
end)
end)
diff --git a/test/functional/legacy/packadd_spec.lua b/test/functional/legacy/packadd_spec.lua
index 68bdbf5257..2d851819e3 100644
--- a/test/functional/legacy/packadd_spec.lua
+++ b/test/functional/legacy/packadd_spec.lua
@@ -27,7 +27,7 @@ describe('packadd', function()
endfunc
func Test_packadd()
- call mkdir(s:plugdir . '/plugin', 'p')
+ call mkdir(s:plugdir . '/plugin/also', 'p')
call mkdir(s:plugdir . '/ftdetect', 'p')
call mkdir(s:plugdir . '/after', 'p')
set rtp&
@@ -38,6 +38,10 @@ describe('packadd', function()
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
@@ -45,6 +49,7 @@ describe('packadd', function()
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_true(&rtp =~ (s:plugdir . '\($\|,\)'))
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index 96324bfac5..ebe8af35eb 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -170,9 +170,9 @@ function Screen.new(width, height)
update_menu = false,
visual_bell = false,
suspended = false,
+ mode = 'normal',
_default_attr_ids = nil,
_default_attr_ignore = nil,
- _mode = 'normal',
_mouse_enabled = true,
_attrs = {},
_cursor = {
@@ -374,8 +374,9 @@ function Screen:_handle_mouse_off()
end
function Screen:_handle_mode_change(mode)
- assert(mode == 'insert' or mode == 'replace' or mode == 'normal')
- self._mode = mode
+ assert(mode == 'insert' or mode == 'replace'
+ or mode == 'normal' or mode == 'cmdline')
+ self.mode = mode
end
function Screen:_handle_set_scroll_region(top, bot, left, right)
@@ -549,7 +550,7 @@ function Screen:print_snapshot(attrs, ignore)
if attrs == nil then
attrs = {}
if self._default_attr_ids ~= nil then
- for i, a in ipairs(self._default_attr_ids) do
+ for i, a in pairs(self._default_attr_ids) do
attrs[i] = a
end
end
diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua
index 2b44b92336..d03f98c26f 100644
--- a/test/functional/ui/screen_basic_spec.lua
+++ b/test/functional/ui/screen_basic_spec.lua
@@ -3,6 +3,7 @@ local Screen = require('test.functional.ui.screen')
local spawn, set_session, clear = helpers.spawn, helpers.set_session, helpers.clear
local feed, execute = helpers.feed, helpers.execute
local insert = helpers.insert
+local eq = helpers.eq
if helpers.pending_win32(pending) then return end
@@ -576,4 +577,117 @@ describe('Screen', function()
]])
end)
end)
+
+ describe('mode change', function()
+ before_each(function()
+ screen:try_resize(25, 5)
+ end)
+
+ it('works in normal mode', function()
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]],nil,nil,function ()
+ eq("normal", screen.mode)
+ end)
+ end)
+
+ it('works in insert mode', function()
+ feed('i')
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:-- INSERT --} |
+ ]],nil,nil,function ()
+ eq("insert", screen.mode)
+ end)
+
+ feed('word<esc>')
+ screen:expect([[
+ wor^d |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]], nil, nil, function ()
+ eq("normal", screen.mode)
+ end)
+ end)
+
+ it('works in replace mode', function()
+ feed('R')
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:-- REPLACE --} |
+ ]], nil, nil, function ()
+ eq("replace", screen.mode)
+ end)
+
+ feed('word<esc>')
+ screen:expect([[
+ wor^d |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]], nil, nil, function ()
+ eq("normal", screen.mode)
+ end)
+ end)
+
+ it('works in cmdline mode', function()
+ feed(':')
+ screen:expect([[
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ :^ |
+ ]],nil,nil,function ()
+ eq("cmdline", screen.mode)
+ end)
+
+ feed('<esc>/')
+ screen:expect([[
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ /^ |
+ ]],nil,nil,function ()
+ eq("cmdline", screen.mode)
+ end)
+
+
+ feed('<esc>?')
+ screen:expect([[
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ?^ |
+ ]],nil,nil,function ()
+ eq("cmdline", screen.mode)
+ end)
+
+ feed('<esc>')
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]],nil,nil,function ()
+ eq("normal", screen.mode)
+ end)
+ end)
+ end)
end)