aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorckelsel <ckelsel@hotmail.com>2017-08-30 19:44:19 +0800
committerckelsel <ckelsel@hotmail.com>2017-08-30 19:44:19 +0800
commit9ae353ab44724808a41794589b68c1b4339d572a (patch)
tree7f3091f1b66b1b0eaa240db0186575940c33c86c
parent0b6fa3a553da3b83419c48fcbb6fb3ec413598e0 (diff)
parent5566f30006a73c30dfbdeece2e08830826d28aa4 (diff)
downloadrneovim-9ae353ab44724808a41794589b68c1b4339d572a.tar.gz
rneovim-9ae353ab44724808a41794589b68c1b4339d572a.tar.bz2
rneovim-9ae353ab44724808a41794589b68c1b4339d572a.zip
Merge remote-tracking branch 'upstream/master'
-rw-r--r--runtime/autoload/provider.vim6
-rw-r--r--runtime/autoload/provider/clipboard.vim12
-rw-r--r--runtime/doc/term.txt21
-rw-r--r--runtime/doc/various.txt1
-rw-r--r--src/nvim/CMakeLists.txt5
-rw-r--r--src/nvim/event/process.c3
-rw-r--r--src/nvim/event/rstream.c2
-rw-r--r--src/nvim/event/stream.c2
-rw-r--r--src/nvim/event/wstream.c1
-rw-r--r--src/nvim/ex_cmds2.c97
-rw-r--r--src/nvim/ex_docmd.c4
-rw-r--r--src/nvim/globals.h3
-rw-r--r--src/nvim/indent_c.c33
-rw-r--r--src/nvim/log.c2
-rw-r--r--src/nvim/log.h8
-rw-r--r--src/nvim/main.c40
-rw-r--r--src/nvim/msgpack_rpc/channel.c76
-rw-r--r--src/nvim/msgpack_rpc/helpers.c9
-rw-r--r--src/nvim/normal.c1
-rw-r--r--src/nvim/ops.c15
-rw-r--r--src/nvim/syntax.c229
-rw-r--r--src/nvim/syntax_defs.h10
-rw-r--r--src/nvim/testdir/test_startup.vim52
-rw-r--r--src/nvim/tui/terminfo.c4
-rw-r--r--src/nvim/tui/tui.c70
-rw-r--r--src/nvim/version.c14
-rw-r--r--src/nvim/window.c20
-rw-r--r--test/functional/api/server_requests_spec.lua30
-rw-r--r--test/functional/autocmd/termclose_spec.lua4
-rw-r--r--test/functional/clipboard/clipboard_provider_spec.lua45
-rw-r--r--test/functional/core/job_spec.lua4
-rw-r--r--test/functional/legacy/003_cindent_spec.lua40
-rw-r--r--test/functional/legacy/051_highlight_spec.lua1
-rw-r--r--test/functional/legacy/packadd_spec.lua40
-rw-r--r--test/functional/terminal/ex_terminal_spec.lua28
-rw-r--r--test/functional/terminal/tui_spec.lua8
36 files changed, 650 insertions, 290 deletions
diff --git a/runtime/autoload/provider.vim b/runtime/autoload/provider.vim
index b46ae12b3c..e6514f5ba8 100644
--- a/runtime/autoload/provider.vim
+++ b/runtime/autoload/provider.vim
@@ -2,7 +2,7 @@
let s:stderr = {}
-function! provider#stderr_collector(chan_id, data, event) dict
+function! provider#stderr_collector(chan_id, data, event)
let stderr = get(s:stderr, a:chan_id, [''])
let stderr[-1] .= a:data[0]
call extend(stderr, a:data[1:])
@@ -10,7 +10,9 @@ function! provider#stderr_collector(chan_id, data, event) dict
endfunction
function! provider#clear_stderr(chan_id)
- silent! call remove(s:stderr, a:chan_id)
+ if has_key(s:stderr, a:chan_id)
+ call remove(s:stderr, a:chan_id)
+ endif
endfunction
function! provider#get_stderr(chan_id)
diff --git a/runtime/autoload/provider/clipboard.vim b/runtime/autoload/provider/clipboard.vim
index 8fe53c495a..6454a01c2a 100644
--- a/runtime/autoload/provider/clipboard.vim
+++ b/runtime/autoload/provider/clipboard.vim
@@ -32,7 +32,7 @@ function! s:try_cmd(cmd, ...) abort
if v:shell_error
if !exists('s:did_error_try_cmd')
echohl WarningMsg
- echomsg "clipboard: error: ".(len(out) ? out[0] : '')
+ echomsg "clipboard: error: ".(len(out) ? out[0] : v:shell_error)
echohl None
let s:did_error_try_cmd = 1
endif
@@ -168,5 +168,13 @@ function! s:clipboard.set(lines, regtype, reg) abort
endfunction
function! provider#clipboard#Call(method, args) abort
- return call(s:clipboard[a:method],a:args,s:clipboard)
+ if get(s:, 'here', v:false) " Clipboard provider must not recurse. #7184
+ return 0
+ endif
+ let s:here = v:true
+ try
+ return call(s:clipboard[a:method],a:args,s:clipboard)
+ finally
+ let s:here = v:false
+ endtry
endfunction
diff --git a/runtime/doc/term.txt b/runtime/doc/term.txt
index d99f9b7160..39eb0673c4 100644
--- a/runtime/doc/term.txt
+++ b/runtime/doc/term.txt
@@ -41,16 +41,17 @@ $TERM is also important because it is mirrored by SSH to the remote session,
unlike other common client-end environment variables ($COLORTERM,
$XTERM_VERSION, $VTE_VERSION, $KONSOLE_PROFILE_NAME, $TERM_PROGRAM, ...).
- For this terminal Set $TERM to |builtin-terms|?
-
- iTerm.app "iterm" or "iTerm.app" Y
- anything libvte based "vte" or "vte-256color" Y
- (e.g. GNOME Terminal) (aliases: "gnome", "gnome-256color")
- tmux "tmux" or "tmux-256color" Y
- screen "screen" or "screen-256color" Y
- PuTTY "putty" or "putty-256color" Y
- Terminal.app "nsterm" N
- Linux virtual terminal "linux" or "linux-256color" Y
+ For this terminal Set $TERM to |builtin-terms|
+ -------------------------------------------------------------------------
+ iTerm (original) iterm, iTerm.app N
+ iTerm2 (new capabilities) iterm2, iTerm2.app Y
+ anything libvte-based vte, vte-256color Y
+ (e.g. GNOME Terminal) (aliases: gnome, gnome-256color)
+ tmux tmux, tmux-256color Y
+ screen screen, screen-256color Y
+ PuTTY putty, putty-256color Y
+ Terminal.app nsterm N
+ Linux virtual terminal linux, linux-256color Y
*builtin-terms* *builtin_terms*
If a |terminfo| database is not available, or no entry for the terminal type is
diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt
index f06c062ee3..223a0135b2 100644
--- a/runtime/doc/various.txt
+++ b/runtime/doc/various.txt
@@ -212,7 +212,6 @@ g8 Print the hex values of the bytes used in the
Equivalent to: >
:enew
:call termopen('{cmd}')
- :startinsert
<
See |termopen()|.
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 688912eda6..e2f1f16635 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -10,6 +10,11 @@ if(USE_GCOV)
endif()
endif()
+if(WIN32)
+ # tell MinGW compiler to enable wmain
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -municode")
+endif()
+
set(TOUCHES_DIR ${PROJECT_BINARY_DIR}/touches)
set(GENERATOR_DIR ${CMAKE_CURRENT_LIST_DIR}/generators)
set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto)
diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
index c936583841..8371d3cd48 100644
--- a/src/nvim/event/process.c
+++ b/src/nvim/event/process.c
@@ -233,8 +233,7 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL
switch (proc->type) {
case kProcessTypeUv:
// Close the process's stdin. If the process doesn't close its own
- // stdout/stderr, they will be closed when it exits(possibly due to being
- // terminated after a timeout)
+ // stdout/stderr, they will be closed when it exits (voluntarily or not).
process_close_in(proc);
ILOG("Sending SIGTERM to pid %d", proc->pid);
uv_kill(proc->pid, SIGTERM);
diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c
index 854af474b2..2c4db08b30 100644
--- a/src/nvim/event/rstream.c
+++ b/src/nvim/event/rstream.c
@@ -118,7 +118,7 @@ static void read_cb(uv_stream_t *uvstream, ssize_t cnt, const uv_buf_t *buf)
// to `alloc_cb` will return the same unused pointer(`rbuffer_produced`
// won't be called)
&& cnt != 0) {
- DLOG("Closing Stream (%p): %s (%s)", stream,
+ DLOG("closing Stream: %p: %s (%s)", stream,
uv_err_name((int)cnt), os_strerror((int)cnt));
// Read error or EOF, either way stop the stream and invoke the callback
// with eof == true
diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c
index 60ceff9b24..7c865bfe1e 100644
--- a/src/nvim/event/stream.c
+++ b/src/nvim/event/stream.c
@@ -7,6 +7,7 @@
#include <uv.h>
+#include "nvim/log.h"
#include "nvim/rbuffer.h"
#include "nvim/macros.h"
#include "nvim/event/stream.h"
@@ -81,6 +82,7 @@ void stream_close(Stream *stream, stream_close_cb on_stream_close, void *data)
FUNC_ATTR_NONNULL_ARG(1)
{
assert(!stream->closed);
+ DLOG("closing Stream: %p", stream);
stream->closed = true;
stream->close_cb = on_stream_close;
stream->close_cb_data = data;
diff --git a/src/nvim/event/wstream.c b/src/nvim/event/wstream.c
index f453e5898d..320006890d 100644
--- a/src/nvim/event/wstream.c
+++ b/src/nvim/event/wstream.c
@@ -8,6 +8,7 @@
#include <uv.h>
+#include "nvim/log.h"
#include "nvim/event/loop.h"
#include "nvim/event/wstream.h"
#include "nvim/vim.h"
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 33fe30cd5a..371f7b3bce 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -2319,16 +2319,6 @@ static void source_callback(char_u *fname, void *cookie)
(void)do_source(fname, false, DOSO_NONE);
}
-/// Source the file "name" from all directories in 'runtimepath'.
-/// "name" can contain wildcards.
-/// When "flags" has DIP_ALL: source all files, otherwise only the first one.
-///
-/// return FAIL when no file could be sourced, OK otherwise.
-int source_runtime(char_u *name, int flags)
-{
- return do_in_runtimepath(name, flags, source_callback, NULL);
-}
-
/// Find the file "name" in all directories in "path" and invoke
/// "callback(fname, cookie)".
/// "name" can contain wildcards.
@@ -2434,21 +2424,21 @@ int do_in_path(char_u *path, char_u *name, int flags,
return did_one ? OK : FAIL;
}
-/// Find "name" in 'runtimepath'. When found, invoke the callback function for
+/// Find "name" in "path". When found, invoke the callback function for
/// it: callback(fname, "cookie")
/// When "flags" has DIP_ALL repeat for all matches, otherwise only the first
/// one is used.
/// Returns OK when at least one match found, FAIL otherwise.
-/// If "name" is NULL calls callback for each entry in runtimepath. Cookie is
+/// If "name" is NULL calls callback for each entry in "path". Cookie is
/// passed by reference in this case, setting it to NULL indicates that callback
/// has done its job.
-int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback,
- void *cookie)
+int do_in_path_and_pp(char_u *path, char_u *name, int flags,
+ DoInRuntimepathCB callback, void *cookie)
{
int done = FAIL;
if ((flags & DIP_NORTP) == 0) {
- done = do_in_path(p_rtp, name, flags, callback, cookie);
+ done = do_in_path(path, name, flags, callback, cookie);
}
if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_START)) {
@@ -2476,6 +2466,29 @@ int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback,
return done;
}
+/// Just like do_in_path_and_pp(), using 'runtimepath' for "path".
+int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback,
+ void *cookie)
+{
+ return do_in_path_and_pp(p_rtp, name, flags, callback, cookie);
+}
+
+/// Source the file "name" from all directories in 'runtimepath'.
+/// "name" can contain wildcards.
+/// When "flags" has DIP_ALL: source all files, otherwise only the first one.
+///
+/// return FAIL when no file could be sourced, OK otherwise.
+int source_runtime(char_u *name, int flags)
+{
+ return source_in_path(p_rtp, name, flags);
+}
+
+/// Just like source_runtime(), but use "path" instead of 'runtimepath'.
+int source_in_path(char_u *path, char_u *name, int flags)
+{
+ return do_in_path_and_pp(path, name, flags, source_callback, NULL);
+}
+
// Expand wildcards in "pat" and invoke do_source() for each match.
static void source_all_matches(char_u *pat)
{
@@ -2498,6 +2511,7 @@ static int APP_BOTH;
static void add_pack_plugin(char_u *fname, void *cookie)
{
char_u *p4, *p3, *p2, *p1, *p;
+ char_u *buf = NULL;
char *const ffname = fix_fname((char *)fname);
@@ -2525,26 +2539,30 @@ static void add_pack_plugin(char_u *fname, void *cookie)
// Find "ffname" in "p_rtp", ignoring '/' vs '\' differences
size_t fname_len = strlen(ffname);
const char *insp = (const char *)p_rtp;
- for (;;) {
- if (path_fnamencmp(insp, ffname, fname_len) == 0) {
- break;
+ buf = try_malloc(MAXPATHL);
+ if (buf == NULL) {
+ goto theend;
+ }
+ while (*insp != NUL) {
+ copy_option_part((char_u **)&insp, buf, MAXPATHL, ",");
+ add_pathsep((char *)buf);
+ char *const rtp_ffname = fix_fname((char *)buf);
+ if (rtp_ffname == NULL) {
+ goto theend;
}
- insp = strchr(insp, ',');
- if (insp == NULL) {
+ bool match = path_fnamencmp(rtp_ffname, ffname, fname_len) == 0;
+ xfree(rtp_ffname);
+ if (match) {
break;
}
- insp++;
}
- if (insp == NULL) {
+ if (*insp == NUL) {
// not found, append at the end
insp = (const char *)p_rtp + STRLEN(p_rtp);
} else {
// append after the matching directory.
- insp += strlen(ffname);
- while (*insp != NUL && *insp != ',') {
- insp++;
- }
+ insp--;
}
*p4 = c;
@@ -2614,26 +2632,35 @@ static void add_pack_plugin(char_u *fname, void *cookie)
}
theend:
+ xfree(buf);
xfree(ffname);
}
-static bool did_source_packages = false;
+/// Add all packages in the "start" directory to 'runtimepath'.
+void add_pack_start_dirs(void)
+{
+ do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
+ add_pack_plugin, &APP_ADD_DIR);
+}
+
+/// Load plugins from all packages in the "start" directory.
+void load_start_packages(void)
+{
+ did_source_packages = true;
+ do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
+ add_pack_plugin, &APP_LOAD);
+}
// ":packloadall"
// Find plugins in the package directories and source them.
-// "eap" is NULL when invoked during startup.
void ex_packloadall(exarg_T *eap)
{
- if (!did_source_packages || (eap != NULL && eap->forceit)) {
- did_source_packages = true;
-
+ if (!did_source_packages || eap->forceit) {
// First do a round to add all directories to 'runtimepath', then load
// the plugins. This allows for plugins to use an autoload directory
// of another plugin.
- do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
- add_pack_plugin, &APP_ADD_DIR);
- do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
- add_pack_plugin, &APP_LOAD);
+ add_pack_start_dirs();
+ load_start_packages();
}
}
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 6e7938046a..d1405978b3 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -9835,7 +9835,7 @@ static void ex_terminal(exarg_T *eap)
if (*eap->arg != NUL) { // Run {cmd} in 'shell'.
char *name = (char *)vim_strsave_escaped(eap->arg, (char_u *)"\"\\");
snprintf(ex_cmd, sizeof(ex_cmd),
- ":enew%s | call termopen(\"%s\") | startinsert",
+ ":enew%s | call termopen(\"%s\")",
eap->forceit ? "!" : "", name);
xfree(name);
} else { // No {cmd}: run the job with tokenized 'shell'.
@@ -9857,7 +9857,7 @@ static void ex_terminal(exarg_T *eap)
shell_free_argv(argv);
snprintf(ex_cmd, sizeof(ex_cmd),
- ":enew%s | call termopen([%s]) | startinsert",
+ ":enew%s | call termopen([%s])",
eap->forceit ? "!" : "", shell_argv + 1);
}
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 13ecafcbe3..2ee72cdb6a 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -407,6 +407,9 @@ EXTERN int garbage_collect_at_exit INIT(= FALSE);
/* ID of script being sourced or was sourced to define the current function. */
EXTERN scid_T current_SID INIT(= 0);
+
+EXTERN bool did_source_packages INIT(= false);
+
// Scope information for the code that indirectly triggered the current
// provider function call
EXTERN struct caller_scope {
diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c
index fd194a4080..4a6393ac36 100644
--- a/src/nvim/indent_c.c
+++ b/src/nvim/indent_c.c
@@ -515,34 +515,41 @@ int cin_isscopedecl(char_u *s)
/* Maximum number of lines to search back for a "namespace" line. */
#define FIND_NAMESPACE_LIM 20
-/*
- * Recognize a "namespace" scope declaration.
- */
-static int cin_is_cpp_namespace(char_u *s)
+// Recognize a "namespace" scope declaration.
+static bool cin_is_cpp_namespace(char_u *s)
{
- char_u *p;
- int has_name = FALSE;
+ char_u *p;
+ bool has_name = false;
+ bool has_name_start = false;
s = cin_skipcomment(s);
if (STRNCMP(s, "namespace", 9) == 0 && (s[9] == NUL || !vim_iswordc(s[9]))) {
p = cin_skipcomment(skipwhite(s + 9));
while (*p != NUL) {
if (ascii_iswhite(*p)) {
- has_name = TRUE; /* found end of a name */
+ has_name = true; // found end of a name
p = cin_skipcomment(skipwhite(p));
} else if (*p == '{') {
break;
} else if (vim_iswordc(*p)) {
- if (has_name)
- return FALSE; /* word character after skipping past name */
- ++p;
+ has_name_start = true;
+ if (has_name) {
+ return false; // word character after skipping past name
+ }
+ p++;
+ } else if (p[0] == ':' && p[1] == ':' && vim_iswordc(p[2])) {
+ if (!has_name_start || has_name) {
+ return false;
+ }
+ // C++ 17 nested namespace
+ p += 3;
} else {
- return FALSE;
+ return false;
}
}
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
/*
diff --git a/src/nvim/log.c b/src/nvim/log.c
index 3baf0b2ebd..436a8a4079 100644
--- a/src/nvim/log.c
+++ b/src/nvim/log.c
@@ -250,7 +250,7 @@ static bool v_do_log_to_file(FILE *log_file, int log_level,
static const char *log_levels[] = {
[DEBUG_LOG_LEVEL] = "DEBUG",
[INFO_LOG_LEVEL] = "INFO ",
- [WARNING_LOG_LEVEL] = "WARN ",
+ [WARN_LOG_LEVEL] = "WARN ",
[ERROR_LOG_LEVEL] = "ERROR",
};
assert(log_level >= DEBUG_LOG_LEVEL && log_level <= ERROR_LOG_LEVEL);
diff --git a/src/nvim/log.h b/src/nvim/log.h
index 5064d9333b..d63bcc366c 100644
--- a/src/nvim/log.h
+++ b/src/nvim/log.h
@@ -6,7 +6,7 @@
#define DEBUG_LOG_LEVEL 0
#define INFO_LOG_LEVEL 1
-#define WARNING_LOG_LEVEL 2
+#define WARN_LOG_LEVEL 2
#define ERROR_LOG_LEVEL 3
#define DLOG(...)
@@ -43,12 +43,12 @@
__VA_ARGS__)
#endif
-#if MIN_LOG_LEVEL <= WARNING_LOG_LEVEL
+#if MIN_LOG_LEVEL <= WARN_LOG_LEVEL
# undef WLOG
# undef WLOGN
-# define WLOG(...) do_log(WARNING_LOG_LEVEL, __func__, __LINE__, true, \
+# define WLOG(...) do_log(WARN_LOG_LEVEL, __func__, __LINE__, true, \
__VA_ARGS__)
-# define WLOGN(...) do_log(WARNING_LOG_LEVEL, __func__, __LINE__, false, \
+# define WLOGN(...) do_log(WARN_LOG_LEVEL, __func__, __LINE__, false, \
__VA_ARGS__)
#endif
diff --git a/src/nvim/main.c b/src/nvim/main.c
index a665ad1de2..024c56dd05 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -7,6 +7,11 @@
#include <string.h>
#include <stdbool.h>
+#ifdef WIN32
+# include <wchar.h>
+# include <winnls.h>
+#endif
+
#include <msgpack.h>
#include "nvim/ascii.h"
@@ -215,10 +220,22 @@ void early_init(void)
#ifdef MAKE_LIB
int nvim_main(int argc, char **argv)
+#elif defined(WIN32)
+int wmain(int argc, wchar_t **argv_w) // multibyte args on Windows. #7060
#else
int main(int argc, char **argv)
#endif
{
+#if defined(WIN32) && !defined(MAKE_LIB)
+ char *argv[argc];
+ for (int i = 0; i < argc; i++) {
+ char *buf = NULL;
+ utf16_to_utf8(argv_w[i], &buf);
+ assert(buf);
+ argv[i] = buf;
+ }
+#endif
+
argv0 = argv[0];
char_u *fname = NULL; // file name from command line
@@ -1291,10 +1308,29 @@ static void set_window_layout(mparm_T *paramp)
static void load_plugins(void)
{
if (p_lpl) {
- source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL | DIP_NOAFTER); // NOLINT
+ char_u *rtp_copy = NULL;
+
+ // First add all package directories to 'runtimepath', so that their
+ // autoload directories can be found. Only if not done already with a
+ // :packloadall command.
+ // Make a copy of 'runtimepath', so that source_runtime does not use the
+ // pack directories.
+ if (!did_source_packages) {
+ rtp_copy = vim_strsave(p_rtp);
+ add_pack_start_dirs();
+ }
+
+ source_in_path(rtp_copy == NULL ? p_rtp : rtp_copy,
+ (char_u *)"plugin/**/*.vim", // NOLINT
+ DIP_ALL | DIP_NOAFTER);
TIME_MSG("loading plugins");
+ xfree(rtp_copy);
- ex_packloadall(NULL);
+ // Only source "start" packages if not done already with a :packloadall
+ // command.
+ if (!did_source_packages) {
+ load_start_packages();
+ }
TIME_MSG("loading packages");
source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL | DIP_AFTER);
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index 6fd1af1ba6..02f3854f47 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -62,7 +62,7 @@ typedef struct {
ChannelType type;
msgpack_unpacker *unpacker;
union {
- Stream stream;
+ Stream stream; // bidirectional (socket)
Process *proc;
struct {
Stream in;
@@ -133,6 +133,9 @@ uint64_t channel_from_process(Process *proc, uint64_t id, char *source)
rstream_init(proc->out, 0);
rstream_start(proc->out, receive_msgpack, channel);
+ DLOG("ch %" PRIu64 " in-stream=%p out-stream=%p", channel->id, proc->in,
+ proc->out);
+
return channel->id;
}
@@ -150,6 +153,9 @@ void channel_from_connection(SocketWatcher *watcher)
wstream_init(&channel->data.stream, 0);
rstream_init(&channel->data.stream, CHANNEL_BUFFER_SIZE);
rstream_start(&channel->data.stream, receive_msgpack, channel);
+
+ DLOG("ch %" PRIu64 " in/out-stream=%p", channel->id,
+ &channel->data.stream);
}
/// @param source description of source function, rplugin name, TCP addr, etc
@@ -344,6 +350,9 @@ void channel_from_stdio(void)
rstream_start(&channel->data.std.in, receive_msgpack, channel);
// write stream
wstream_init_fd(&main_loop, &channel->data.std.out, 1, 0);
+
+ DLOG("ch %" PRIu64 " in-stream=%p out-stream=%p", channel->id,
+ &channel->data.std.in, &channel->data.std.out);
}
/// Creates a loopback channel. This is used to avoid deadlock
@@ -363,6 +372,7 @@ void channel_process_exit(uint64_t id, int status)
decref(channel);
}
+// rstream.c:read_event() invokes this as stream->read_cb().
static void receive_msgpack(Stream *stream, RBuffer *rbuf, size_t c,
void *data, bool eof)
{
@@ -374,12 +384,24 @@ static void receive_msgpack(Stream *stream, RBuffer *rbuf, size_t c,
char buf[256];
snprintf(buf, sizeof(buf), "ch %" PRIu64 " was closed by the client",
channel->id);
- call_set_error(channel, buf, WARNING_LOG_LEVEL);
+ call_set_error(channel, buf, WARN_LOG_LEVEL);
+ goto end;
+ }
+
+ if ((chan_wstream(channel) != NULL && chan_wstream(channel)->closed)
+ || (chan_rstream(channel) != NULL && chan_rstream(channel)->closed)) {
+ char buf[256];
+ snprintf(buf, sizeof(buf),
+ "ch %" PRIu64 ": stream closed unexpectedly. "
+ "closing channel",
+ channel->id);
+ call_set_error(channel, buf, WARN_LOG_LEVEL);
goto end;
}
size_t count = rbuffer_size(rbuf);
- DLOG("parsing %u bytes of msgpack data from Stream(%p)", count, stream);
+ DLOG("ch %" PRIu64 ": parsing %u bytes from msgpack Stream: %p",
+ channel->id, count, stream);
// Feed the unpacker with data
msgpack_unpacker_reserve_buffer(channel->unpacker, count);
@@ -435,8 +457,8 @@ static void parse_msgpack(Channel *channel)
// causes for this error(search for 'goto _failed')
//
// A not so uncommon cause for this might be deserializing objects with
- // a high nesting level: msgpack will break when it's internal parse stack
- // size exceeds MSGPACK_EMBED_STACK_SIZE(defined as 32 by default)
+ // a high nesting level: msgpack will break when its internal parse stack
+ // size exceeds MSGPACK_EMBED_STACK_SIZE (defined as 32 by default)
send_error(channel, 0, "Invalid msgpack payload. "
"This error can also happen when deserializing "
"an object with high level of nesting");
@@ -534,6 +556,39 @@ static void on_request_event(void **argv)
api_clear_error(&error);
}
+/// Returns the Stream that a Channel writes to.
+static Stream *chan_wstream(Channel *chan)
+{
+ switch (chan->type) {
+ case kChannelTypeSocket:
+ return &chan->data.stream;
+ case kChannelTypeProc:
+ return chan->data.proc->in;
+ case kChannelTypeStdio:
+ return &chan->data.std.out;
+ case kChannelTypeInternal:
+ return NULL;
+ }
+ abort();
+}
+
+/// Returns the Stream that a Channel reads from.
+static Stream *chan_rstream(Channel *chan)
+{
+ switch (chan->type) {
+ case kChannelTypeSocket:
+ return &chan->data.stream;
+ case kChannelTypeProc:
+ return chan->data.proc->out;
+ case kChannelTypeStdio:
+ return &chan->data.std.in;
+ case kChannelTypeInternal:
+ return NULL;
+ }
+ abort();
+}
+
+
static bool channel_write(Channel *channel, WBuffer *buffer)
{
bool success = false;
@@ -545,13 +600,9 @@ static bool channel_write(Channel *channel, WBuffer *buffer)
switch (channel->type) {
case kChannelTypeSocket:
- success = wstream_write(&channel->data.stream, buffer);
- break;
case kChannelTypeProc:
- success = wstream_write(channel->data.proc->in, buffer);
- break;
case kChannelTypeStdio:
- success = wstream_write(&channel->data.std.out, buffer);
+ success = wstream_write(chan_wstream(channel), buffer);
break;
case kChannelTypeInternal:
incref(channel);
@@ -565,8 +616,8 @@ static bool channel_write(Channel *channel, WBuffer *buffer)
char buf[256];
snprintf(buf,
sizeof(buf),
- "Before returning from a RPC call, ch %" PRIu64 " was "
- "closed due to a failed write",
+ "ch %" PRIu64 ": stream write failed. "
+ "RPC canceled; closing channel",
channel->id);
call_set_error(channel, buf, ERROR_LOG_LEVEL);
}
@@ -817,6 +868,7 @@ static void call_set_error(Channel *channel, char *msg, int loglevel)
ChannelCallFrame *frame = kv_A(channel->call_stack, i);
frame->returned = true;
frame->errored = true;
+ api_free_object(frame->result);
frame->result = STRING_OBJ(cstr_to_string(msg));
}
diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c
index 444c6cc256..fecae11d45 100644
--- a/src/nvim/msgpack_rpc/helpers.c
+++ b/src/nvim/msgpack_rpc/helpers.c
@@ -88,7 +88,12 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
{
bool ret = true;
kvec_t(MPToAPIObjectStackItem) stack = KV_INITIAL_VALUE;
- kv_push(stack, ((MPToAPIObjectStackItem) { obj, arg, false, 0 }));
+ kv_push(stack, ((MPToAPIObjectStackItem) {
+ .mobj = obj,
+ .aobj = arg,
+ .container = false,
+ .idx = 0,
+ }));
while (ret && kv_size(stack)) {
MPToAPIObjectStackItem cur = kv_last(stack);
if (!cur.container) {
@@ -361,7 +366,7 @@ typedef struct {
size_t idx;
} APIToMPObjectStackItem;
-/// Convert type used by Neovim API to msgpack
+/// Convert type used by Nvim API to msgpack type.
///
/// @param[in] result Object to convert.
/// @param[out] res Structure that defines where conversion results are saved.
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index c1676780d8..238378c474 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -13,6 +13,7 @@
#include <stdbool.h>
#include <stdlib.h>
+#include "nvim/log.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/normal.h"
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 6c873a96c0..c01840cfd0 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -55,12 +55,11 @@ static yankreg_T y_regs[NUM_REGISTERS];
static yankreg_T *y_previous = NULL; /* ptr to last written yankreg */
-static bool clipboard_didwarn_unnamed = false;
-
// for behavior between start_batch_changes() and end_batch_changes())
static int batch_change_count = 0; // inside a script
static bool clipboard_delay_update = false; // delay clipboard update
static bool clipboard_needs_update = false; // clipboard was updated
+static bool clipboard_didwarn = false;
/*
* structure used by block_prep, op_delete and op_yank for blockwise operators
@@ -5541,22 +5540,17 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing)
yankreg_T *target = NULL;
bool explicit_cb_reg = (*name == '*' || *name == '+');
bool implicit_cb_reg = (*name == NUL) && (cb_flags & CB_UNNAMEDMASK);
- int save_redir_off = redir_off;
if (!explicit_cb_reg && !implicit_cb_reg) {
goto end;
}
if (!eval_has_provider("clipboard")) {
- if (batch_change_count == 1 && explicit_cb_reg && !quiet) {
- redir_off = true; // Avoid recursion from :redir + emsg().
+ if (batch_change_count == 1 && !quiet
+ && (!clipboard_didwarn || (explicit_cb_reg && !redirecting()))) {
+ clipboard_didwarn = true;
// Do NOT error (emsg()) here--if it interrupts :redir we get into
// a weird state, stuck in "redirect mode".
msg((char_u *)MSG_NO_CLIP);
- } else if (batch_change_count == 1 && implicit_cb_reg
- && !quiet && !clipboard_didwarn_unnamed) {
- redir_off = true; // Avoid recursion from :redir + emsg().
- msg((char_u *)MSG_NO_CLIP);
- clipboard_didwarn_unnamed = true;
}
// ... else, be silent (don't flood during :while, :redir, etc.).
goto end;
@@ -5586,7 +5580,6 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing)
}
end:
- redir_off = save_redir_off;
return target;
}
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index f0171fa525..65c0e2464a 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -81,7 +81,10 @@ struct hl_group {
// highlight groups for 'highlight' option
static garray_T highlight_ga = GA_EMPTY_INIT_VALUE;
-#define HL_TABLE() ((struct hl_group *)((highlight_ga.ga_data)))
+static inline struct hl_group * HL_TABLE(void)
+{
+ return ((struct hl_group *)((highlight_ga.ga_data)));
+}
#define MAX_HL_ID 20000 /* maximum value for a highlight ID. */
@@ -100,10 +103,8 @@ static int include_none = 0; /* when 1 include "nvim/None" */
static int include_default = 0; /* when 1 include "nvim/default" */
static int include_link = 0; /* when 2 include "nvim/link" and "clear" */
-/*
- * The "term", "cterm" and "gui" arguments can be any combination of the
- * following names, separated by commas (but no spaces!).
- */
+/// The "term", "cterm" and "gui" arguments can be any combination of the
+/// following names, separated by commas (but no spaces!).
static char *(hl_name_table[]) =
{"bold", "standout", "underline", "undercurl",
"italic", "reverse", "inverse", "NONE"};
@@ -1775,8 +1776,9 @@ syn_current_attr (
cur_si->si_trans_id = CUR_STATE(
current_state.ga_len - 2).si_trans_id;
}
- } else
+ } else {
cur_si->si_attr = syn_id2attr(syn_id);
+ }
cur_si->si_cont_list = NULL;
cur_si->si_next_list = next_list;
check_keepend();
@@ -5252,12 +5254,10 @@ get_id_list (
/*
* Handle full group name.
*/
- if (vim_strpbrk(name + 1, (char_u *)"\\.*^$~[") == NULL)
+ if (vim_strpbrk(name + 1, (char_u *)"\\.*^$~[") == NULL) {
id = syn_check_group(name + 1, (int)(end - p));
- else {
- /*
- * Handle match of regexp with group names.
- */
+ } else {
+ // Handle match of regexp with group names.
*name = '^';
STRCAT(name, "$");
regmatch.regprog = vim_regcomp(name, RE_MAGIC);
@@ -5958,6 +5958,7 @@ static char *highlight_init_light[] =
"Title ctermfg=DarkMagenta gui=bold guifg=Magenta",
"Visual guibg=LightGrey",
"WarningMsg ctermfg=DarkRed guifg=Red",
+ "Normal gui=NONE",
NULL
};
@@ -5991,23 +5992,25 @@ static char *highlight_init_dark[] =
"Title ctermfg=LightMagenta gui=bold guifg=Magenta",
"Visual guibg=DarkGrey",
"WarningMsg ctermfg=LightRed guifg=Red",
+ "Normal gui=NONE",
NULL
};
-void
-init_highlight (
- int both, /* include groups where 'bg' doesn't matter */
- int reset /* clear group first */
-)
+
+/// Load colors from a file if "g:colors_name" is set, otherwise load builtin
+/// colors
+///
+/// @param both include groups where 'bg' doesn't matter
+/// @param reset clear groups first
+void
+init_highlight(int both, int reset)
{
int i;
char **pp;
static int had_both = FALSE;
- /*
- * Try finding the color scheme file. Used when a color file was loaded
- * and 'background' or 't_Co' is changed.
- */
+ // Try finding the color scheme file. Used when a color file was loaded
+ // and 'background' or 't_Co' is changed.
char_u *p = get_var_value("g:colors_name");
if (p != NULL) {
// Value of g:colors_name could be freed in load_colors() and make
@@ -6026,33 +6029,34 @@ init_highlight (
if (both) {
had_both = TRUE;
pp = highlight_init_both;
- for (i = 0; pp[i] != NULL; ++i)
- do_highlight((char_u *)pp[i], reset, TRUE);
- } else if (!had_both)
- /* Don't do anything before the call with both == TRUE from main().
- * Not everything has been setup then, and that call will overrule
- * everything anyway. */
+ for (i = 0; pp[i] != NULL; i++) {
+ do_highlight((char_u *)pp[i], reset, true);
+ }
+ } else if (!had_both) {
+ // Don't do anything before the call with both == TRUE from main().
+ // Not everything has been setup then, and that call will overrule
+ // everything anyway.
return;
+ }
- if (*p_bg == 'l')
- pp = highlight_init_light;
- else
- pp = highlight_init_dark;
- for (i = 0; pp[i] != NULL; ++i)
- do_highlight((char_u *)pp[i], reset, TRUE);
+ pp = (*p_bg == 'l') ? highlight_init_light : highlight_init_dark;
+
+ for (i = 0; pp[i] != NULL; i++) {
+ do_highlight((char_u *)pp[i], reset, true);
+ }
/* Reverse looks ugly, but grey may not work for 8 colors. Thus let it
* depend on the number of colors available.
* With 8 colors brown is equal to yellow, need to use black for Search fg
* to avoid Statement highlighted text disappears.
* Clear the attributes, needed when changing the t_Co value. */
- if (t_colors > 8)
+ if (t_colors > 8) {
do_highlight(
(char_u *)(*p_bg == 'l'
? "Visual cterm=NONE ctermbg=LightGrey"
- : "Visual cterm=NONE ctermbg=DarkGrey"), FALSE,
- TRUE);
- else {
+ : "Visual cterm=NONE ctermbg=DarkGrey"), false,
+ true);
+ } else {
do_highlight((char_u *)"Visual cterm=reverse ctermbg=NONE",
FALSE, TRUE);
if (*p_bg == 'l')
@@ -6112,12 +6116,7 @@ int load_colors(char_u *name)
/// "forceit" and "init" both TRUE.
/// @param init TRUE when called for initializing
void
-do_highlight(
- char_u *line,
- int forceit,
- int init
-)
-{
+do_highlight(char_u *line, int forceit, int init) {
char_u *name_end;
char_u *linep;
char_u *key_start;
@@ -6134,15 +6133,16 @@ do_highlight(
int dolink = FALSE;
int error = FALSE;
int color;
- int is_normal_group = FALSE; /* "Normal" group */
+ bool is_normal_group = false; // "Normal" group
/*
* If no argument, list current highlighting.
*/
if (ends_excmd(*line)) {
- for (int i = 1; i <= highlight_ga.ga_len && !got_int; ++i)
- /* TODO: only call when the group has attributes set */
+ for (int i = 1; i <= highlight_ga.ga_len && !got_int; i++) {
+ // todo(vim): only call when the group has attributes set
highlight_list_one(i);
+ }
return;
}
@@ -6270,12 +6270,12 @@ do_highlight(
return;
idx = id - 1; /* index is ID minus one */
- /* Return if "default" was used and the group already has settings. */
- if (dodefault && hl_has_settings(idx, TRUE))
+ // Return if "default" was used and the group already has settings
+ if (dodefault && hl_has_settings(idx, true)) {
return;
+ }
- if (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0)
- is_normal_group = TRUE;
+ is_normal_group = (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0);
/* Clear the highlighting for ":hi clear {group}" and ":hi clear". */
if (doclear || (forceit && init)) {
@@ -6284,7 +6284,7 @@ do_highlight(
HL_TABLE()[idx].sg_set = 0;
}
- if (!doclear)
+ if (!doclear) {
while (!ends_excmd(*linep)) {
key_start = linep;
if (*linep == '=') {
@@ -6390,12 +6390,12 @@ do_highlight(
}
}
} else if (STRCMP(key, "FONT") == 0) {
- /* in non-GUI fonts are simply ignored */
- } else if (STRCMP(key,
- "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) {
+ // in non-GUI fonts are simply ignored
+ } else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) {
if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) {
- if (!init)
+ if (!init) {
HL_TABLE()[idx].sg_set |= SG_CTERM;
+ }
/* When setting the foreground color, and previously the "bold"
* flag was set for a light color, reset it now */
@@ -6489,9 +6489,10 @@ do_highlight(
* colors (on some terminals, e.g. "linux") */
if (color & 8) {
HL_TABLE()[idx].sg_cterm |= HL_BOLD;
- HL_TABLE()[idx].sg_cterm_bold = TRUE;
- } else
+ HL_TABLE()[idx].sg_cterm_bold = true;
+ } else {
HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
+ }
}
color &= 7; // truncate to 8 colors
} else if (t_colors == 16 || t_colors == 88 || t_colors >= 256) {
@@ -6603,21 +6604,23 @@ do_highlight(
/*
* When highlighting has been given for a group, don't link it.
*/
- if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK))
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK)) {
HL_TABLE()[idx].sg_link = 0;
+ }
/*
* Continue with next argument.
*/
linep = skipwhite(linep);
}
+ }
/*
* If there is an error, and it's a new entry, remove it from the table.
*/
- if (error && idx == highlight_ga.ga_len)
+ if (error && idx == highlight_ga.ga_len) {
syn_unadd_group();
- else {
+ } else {
if (is_normal_group) {
HL_TABLE()[idx].sg_attr = 0;
// Need to update all groups, because they might be using "bg" and/or
@@ -6625,16 +6628,17 @@ do_highlight(
highlight_attr_set_all();
// If the normal group has changed, it is simpler to refresh every UI
ui_refresh();
- } else
+ } else {
set_hl_attr(idx);
+ }
HL_TABLE()[idx].sg_scriptID = current_SID;
redraw_all_later(NOT_VALID);
}
xfree(key);
xfree(arg);
- /* Only call highlight_changed() once, after sourcing a syntax file */
- need_highlight_changed = TRUE;
+ // Only call highlight_changed() once, after sourcing a syntax file
+ need_highlight_changed = true;
}
#if defined(EXITFREE)
@@ -6707,14 +6711,15 @@ static void highlight_clear(int idx)
}
-/*
- * Table with the specifications for an attribute number.
- * Note that this table is used by ALL buffers. This is required because the
- * GUI can redraw at any time for any buffer.
- */
+/// Table with the specifications for an attribute number.
+/// Note that this table is used by ALL buffers. This is required because the
+/// GUI can redraw at any time for any buffer.
static garray_T attr_table = GA_EMPTY_INIT_VALUE;
-#define ATTR_ENTRY(idx) ((attrentry_T *)attr_table.ga_data)[idx]
+static inline attrentry_T * ATTR_ENTRY(int idx)
+{
+ return &((attrentry_T *)attr_table.ga_data)[idx];
+}
/// Return the attr number for a set of colors and font.
@@ -6804,7 +6809,7 @@ int hl_combine_attr(int char_attr, int prim_attr)
{
attrentry_T *char_aep = NULL;
attrentry_T *spell_aep;
- attrentry_T new_en;
+ attrentry_T new_en = ATTRENTRY_INIT;
if (char_attr == 0) {
return prim_attr;
@@ -6852,17 +6857,24 @@ int hl_combine_attr(int char_attr, int prim_attr)
return get_attr_entry(&new_en);
}
+/// \note this function does not apply exclusively to cterm attr contrary
+/// to what its name implies
attrentry_T *syn_cterm_attr2entry(int attr)
{
attr -= ATTR_OFF;
- if (attr >= attr_table.ga_len) /* did ":syntax clear" */
+ if (attr >= attr_table.ga_len) {
+ // did ":syntax clear"
return NULL;
- return &(ATTR_ENTRY(attr));
+ }
+ return ATTR_ENTRY(attr);
}
+/// \addtogroup LIST_XXX
+/// @{
#define LIST_ATTR 1
#define LIST_STRING 2
#define LIST_INT 3
+/// @}
static void highlight_list_one(int id)
{
@@ -6901,7 +6913,13 @@ static void highlight_list_one(int id)
last_set_msg(sgp->sg_scriptID);
}
-static int highlight_list_arg(int id, int didh, int type, int iarg, char_u *sarg, char *name)
+/// Outputs a highlight when doing ":hi MyHighlight"
+///
+/// @param type one of \ref LIST_XXX
+/// @param iarg integer argument used if \p type == LIST_INT
+/// @param sarg string used if \p type == LIST_STRING
+static int highlight_list_arg(int id, int didh, int type, int iarg,
+ char_u *sarg, const char *name)
{
char_u buf[100];
char_u *ts;
@@ -7041,24 +7059,23 @@ const char *highlight_color(const int id, const char *const what,
return NULL;
}
-/*
- * Output the syntax list header.
- * Return TRUE when started a new line.
- */
-static int
-syn_list_header (
- int did_header, /* did header already */
- int outlen, /* length of string that comes */
- int id /* highlight group id */
-)
+/// Output the syntax list header.
+///
+/// @param did_header did header already
+/// @param outlen length of string that comes
+/// @param id highlight group id
+/// @return true when started a new line.
+static int
+syn_list_header(int did_header, int outlen, int id)
{
int endcol = 19;
int newline = TRUE;
if (!did_header) {
msg_putchar('\n');
- if (got_int)
- return TRUE;
+ if (got_int) {
+ return true;
+ }
msg_outtrans(HL_TABLE()[id - 1].sg_name);
endcol = 15;
} else if (msg_col + outlen + 1 >= Columns) {
@@ -7095,12 +7112,13 @@ set_hl_attr (
int idx /* index in array */
)
{
- attrentry_T at_en;
+ attrentry_T at_en = ATTRENTRY_INIT;
struct hl_group *sgp = HL_TABLE() + idx;
- /* The "Normal" group doesn't need an attribute number */
- if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0)
+ // The "Normal" group doesn't need an attribute number
+ if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0) {
return;
+ }
at_en.cterm_ae_attr = sgp->sg_cterm;
at_en.cterm_fg_color = sgp->sg_cterm_fg;
@@ -7124,10 +7142,10 @@ set_hl_attr (
}
}
-/*
- * Lookup a highlight group name and return it's ID.
- * If it is not found, 0 is returned.
- */
+/// Lookup a highlight group name and return its ID.
+///
+/// @param highlight name e.g. 'Cursor', 'Normal'
+/// @return the highlight id, else 0 if \p name does not exist
int syn_name2id(const char_u *name)
{
int i;
@@ -7176,7 +7194,7 @@ int syn_namen2id(char_u *linep, int len)
return id;
}
-/// Find highlight group name in the table and return it's ID.
+/// Find highlight group name in the table and return its ID.
/// If it doesn't exist yet, a new entry is created.
///
/// @param pp Highlight group name
@@ -7195,11 +7213,11 @@ int syn_check_group(char_u *pp, int len)
return id;
}
-/*
- * Add new highlight group and return it's ID.
- * "name" must be an allocated string, it will be consumed.
- * Return 0 for failure.
- */
+/// Add new highlight group and return it's ID.
+///
+/// @param name must be an allocated string, it will be consumed.
+/// @return 0 for failure, else the allocated group id
+/// @see syn_check_group syn_unadd_group
static int syn_add_group(char_u *name)
{
char_u *p;
@@ -7237,25 +7255,26 @@ static int syn_add_group(char_u *name)
struct hl_group* hlgp = GA_APPEND_VIA_PTR(struct hl_group, &highlight_ga);
memset(hlgp, 0, sizeof(*hlgp));
hlgp->sg_name = name;
+ hlgp->sg_rgb_bg = -1;
+ hlgp->sg_rgb_fg = -1;
+ hlgp->sg_rgb_sp = -1;
hlgp->sg_name_u = vim_strsave_up(name);
return highlight_ga.ga_len; /* ID is index plus one */
}
-/*
- * When, just after calling syn_add_group(), an error is discovered, this
- * function deletes the new name.
- */
+/// When, just after calling syn_add_group(), an error is discovered, this
+/// function deletes the new name.
static void syn_unadd_group(void)
{
- --highlight_ga.ga_len;
+ highlight_ga.ga_len--;
xfree(HL_TABLE()[highlight_ga.ga_len].sg_name);
xfree(HL_TABLE()[highlight_ga.ga_len].sg_name_u);
}
-/*
- * Translate a group ID to highlight attributes.
- */
+
+/// Translate a group ID to highlight attributes.
+/// @see syn_cterm_attr2entry
int syn_id2attr(int hl_id)
{
struct hl_group *sgp;
diff --git a/src/nvim/syntax_defs.h b/src/nvim/syntax_defs.h
index 9f309451b0..56fadbe7f6 100644
--- a/src/nvim/syntax_defs.h
+++ b/src/nvim/syntax_defs.h
@@ -73,4 +73,14 @@ typedef struct attr_entry {
int cterm_fg_color, cterm_bg_color;
} attrentry_T;
+#define ATTRENTRY_INIT { \
+ .rgb_ae_attr = 0, \
+ .cterm_ae_attr = 0, \
+ .rgb_fg_color = -1, \
+ .rgb_bg_color = -1, \
+ .rgb_sp_color = -1, \
+ .cterm_fg_color = 0, \
+ .cterm_bg_color = 0, \
+}
+
#endif // NVIM_SYNTAX_DEFS_H
diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim
index 5a38178bd5..11e26d03aa 100644
--- a/src/nvim/testdir/test_startup.vim
+++ b/src/nvim/testdir/test_startup.vim
@@ -24,28 +24,34 @@ func Test_after_comes_later()
\ 'set guioptions+=M',
\ 'let $HOME = "/does/not/exist"',
\ 'set loadplugins',
- \ 'set rtp=Xhere,Xafter',
+ \ 'set rtp=Xhere,Xafter,Xanother',
\ 'set packpath=Xhere,Xafter',
\ 'set nomore',
+ \ 'let g:sequence = ""',
\ ]
let after = [
\ 'redir! > Xtestout',
\ 'scriptnames',
\ 'redir END',
+ \ 'redir! > Xsequence',
+ \ 'echo g:sequence',
+ \ 'redir END',
\ 'quit',
\ ]
call mkdir('Xhere/plugin', 'p')
- call writefile(['let done = 1'], 'Xhere/plugin/here.vim')
+ call writefile(['let g:sequence .= "here "'], 'Xhere/plugin/here.vim')
+ call mkdir('Xanother/plugin', 'p')
+ call writefile(['let g:sequence .= "another "'], 'Xanother/plugin/another.vim')
call mkdir('Xhere/pack/foo/start/foobar/plugin', 'p')
- call writefile(['let done = 1'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim')
+ call writefile(['let g:sequence .= "pack "'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim')
call mkdir('Xafter/plugin', 'p')
- call writefile(['let done = 1'], 'Xafter/plugin/later.vim')
+ call writefile(['let g:sequence .= "after "'], 'Xafter/plugin/later.vim')
if RunVim(before, after, '')
let lines = readfile('Xtestout')
- let expected = ['Xbefore.vim', 'here.vim', 'foo.vim', 'later.vim', 'Xafter.vim']
+ let expected = ['Xbefore.vim', 'here.vim', 'another.vim', 'foo.vim', 'later.vim', 'Xafter.vim']
let found = []
for line in lines
for one in expected
@@ -57,11 +63,47 @@ func Test_after_comes_later()
call assert_equal(expected, found)
endif
+ call assert_equal('here another pack after', substitute(join(readfile('Xsequence', 1), ''), '\s\+$', '', ''))
+
call delete('Xtestout')
+ call delete('Xsequence')
call delete('Xhere', 'rf')
+ call delete('Xanother', 'rf')
call delete('Xafter', 'rf')
endfunc
+func Test_pack_in_rtp_when_plugins_run()
+ if !has('packages')
+ return
+ endif
+ let before = [
+ \ 'set nocp viminfo+=nviminfo',
+ \ 'set guioptions+=M',
+ \ 'let $HOME = "/does/not/exist"',
+ \ 'set loadplugins',
+ \ 'set rtp=Xhere',
+ \ 'set packpath=Xhere',
+ \ 'set nomore',
+ \ ]
+ let after = [
+ \ 'quit',
+ \ ]
+ call mkdir('Xhere/plugin', 'p')
+ call writefile(['redir! > Xtestout', 'silent set runtimepath?', 'silent! call foo#Trigger()', 'redir END'], 'Xhere/plugin/here.vim')
+ call mkdir('Xhere/pack/foo/start/foobar/autoload', 'p')
+ call writefile(['function! foo#Trigger()', 'echo "autoloaded foo"', 'endfunction'], 'Xhere/pack/foo/start/foobar/autoload/foo.vim')
+
+ if RunVim(before, after, '')
+
+ let lines = filter(readfile('Xtestout'), '!empty(v:val)')
+ call assert_match('Xhere[/\\]pack[/\\]foo[/\\]start[/\\]foobar', get(lines, 0))
+ call assert_match('autoloaded foo', get(lines, 1))
+ endif
+
+ call delete('Xtestout')
+ call delete('Xhere', 'rf')
+endfunc
+
func Test_help_arg()
if !has('unix') && has('gui')
" this doesn't work with gvim on MS-Windows
diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c
index b8fffcb7d6..586fafba97 100644
--- a/src/nvim/tui/terminfo.c
+++ b/src/nvim/tui/terminfo.c
@@ -104,7 +104,9 @@ unibi_term *load_builtin_terminfo(const char * term)
return unibi_from_mem((const char *)interix_8colour_terminfo,
sizeof interix_8colour_terminfo);
} else if (terminfo_is_term_family(term, "iterm")
- || terminfo_is_term_family(term, "iTerm.app")) {
+ || terminfo_is_term_family(term, "iterm2")
+ || terminfo_is_term_family(term, "iTerm.app")
+ || terminfo_is_term_family(term, "iTerm2.app")) {
return unibi_from_mem((const char *)iterm_256colour_terminfo,
sizeof iterm_256colour_terminfo);
} else if (terminfo_is_term_family(term, "st")) {
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index b5af5b0333..dd93053dbf 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -234,9 +234,9 @@ static void terminfo_start(UI *ui)
unibi_out(ui, unibi_keypad_xmit);
unibi_out(ui, unibi_clear_screen);
// Enable bracketed paste
- unibi_out(ui, data->unibi_ext.enable_bracketed_paste);
+ unibi_out_ext(ui, data->unibi_ext.enable_bracketed_paste);
// Enable focus reporting
- unibi_out(ui, data->unibi_ext.enable_focus_reporting);
+ unibi_out_ext(ui, data->unibi_ext.enable_focus_reporting);
uv_loop_init(&data->write_loop);
if (data->out_isatty) {
uv_tty_init(&data->write_loop, &data->output_handle.tty, data->out_fd, 0);
@@ -263,9 +263,9 @@ static void terminfo_stop(UI *ui)
unibi_out(ui, unibi_keypad_local);
unibi_out(ui, unibi_exit_ca_mode);
// Disable bracketed paste
- unibi_out(ui, data->unibi_ext.disable_bracketed_paste);
+ unibi_out_ext(ui, data->unibi_ext.disable_bracketed_paste);
// Disable focus reporting
- unibi_out(ui, data->unibi_ext.disable_focus_reporting);
+ unibi_out_ext(ui, data->unibi_ext.disable_focus_reporting);
flush_buf(ui, true);
uv_tty_reset_mode();
uv_close((uv_handle_t *)&data->output_handle, NULL);
@@ -426,14 +426,14 @@ static void update_attrs(UI *ui, HlAttrs attrs)
data->params[0].i = (fg >> 16) & 0xff; // red
data->params[1].i = (fg >> 8) & 0xff; // green
data->params[2].i = fg & 0xff; // blue
- unibi_out(ui, data->unibi_ext.set_rgb_foreground);
+ unibi_out_ext(ui, data->unibi_ext.set_rgb_foreground);
}
if (bg != -1) {
data->params[0].i = (bg >> 16) & 0xff; // red
data->params[1].i = (bg >> 8) & 0xff; // green
data->params[2].i = bg & 0xff; // blue
- unibi_out(ui, data->unibi_ext.set_rgb_background);
+ unibi_out_ext(ui, data->unibi_ext.set_rgb_background);
}
} else {
if (fg != -1) {
@@ -679,7 +679,7 @@ static void set_scroll_region(UI *ui)
data->params[1].i = grid->bot;
unibi_out(ui, unibi_change_scroll_region);
if (grid->left != 0 || grid->right != ui->width - 1) {
- unibi_out(ui, data->unibi_ext.enable_lr_margin);
+ unibi_out_ext(ui, data->unibi_ext.enable_lr_margin);
if (data->can_set_lr_margin) {
data->params[0].i = grid->left;
data->params[1].i = grid->right;
@@ -700,7 +700,7 @@ static void reset_scroll_region(UI *ui)
UGrid *grid = &data->grid;
if (0 <= data->unibi_ext.reset_scroll_region) {
- unibi_out(ui, data->unibi_ext.reset_scroll_region);
+ unibi_out_ext(ui, data->unibi_ext.reset_scroll_region);
} else {
data->params[0].i = 0;
data->params[1].i = ui->height - 1;
@@ -717,7 +717,7 @@ static void reset_scroll_region(UI *ui)
data->params[0].i = ui->width - 1;
unibi_out(ui, unibi_set_right_margin_parm);
}
- unibi_out(ui, data->unibi_ext.disable_lr_margin);
+ unibi_out_ext(ui, data->unibi_ext.disable_lr_margin);
}
unibi_goto(ui, grid->row, grid->col);
}
@@ -730,7 +730,7 @@ static void tui_resize(UI *ui, Integer width, Integer height)
if (!got_winch) { // Try to resize the terminal window.
data->params[0].i = (int)height;
data->params[1].i = (int)width;
- unibi_out(ui, data->unibi_ext.resize_screen);
+ unibi_out_ext(ui, data->unibi_ext.resize_screen);
// DECSLPP does not reset the scroll region.
if (data->scroll_region_is_full_screen) {
reset_scroll_region(ui);
@@ -836,7 +836,7 @@ static void tui_mouse_on(UI *ui)
{
TUIData *data = ui->data;
if (!data->mouse_enabled) {
- unibi_out(ui, data->unibi_ext.enable_mouse);
+ unibi_out_ext(ui, data->unibi_ext.enable_mouse);
data->mouse_enabled = true;
}
}
@@ -845,7 +845,7 @@ static void tui_mouse_off(UI *ui)
{
TUIData *data = ui->data;
if (data->mouse_enabled) {
- unibi_out(ui, data->unibi_ext.disable_mouse);
+ unibi_out_ext(ui, data->unibi_ext.disable_mouse);
data->mouse_enabled = false;
}
}
@@ -864,7 +864,7 @@ static void tui_set_mode(UI *ui, ModeShape mode)
if (attr > 0) {
attrentry_T *aep = syn_cterm_attr2entry(attr);
data->params[0].i = aep->rgb_bg_color;
- unibi_out(ui, data->unibi_ext.set_cursor_color);
+ unibi_out_ext(ui, data->unibi_ext.set_cursor_color);
}
}
@@ -875,7 +875,7 @@ static void tui_set_mode(UI *ui, ModeShape mode)
default: WLOG("Unknown shape value %d", shape); break;
}
data->params[0].i = shape + (int)(c.blinkon == 0);
- unibi_out(ui, data->unibi_ext.set_cursor_style);
+ unibi_out_ext(ui, data->unibi_ext.set_cursor_style);
}
/// @param mode editor mode
@@ -1182,25 +1182,27 @@ static void unibi_goto(UI *ui, int row, int col)
unibi_out(ui, unibi_cursor_address);
}
+#define UNIBI_OUT(fn) \
+ do { \
+ TUIData *data = ui->data; \
+ const char *str = NULL; \
+ if (unibi_index >= 0) { \
+ str = fn(data->ut, (unsigned)unibi_index); \
+ } \
+ if (str) { \
+ unibi_var_t vars[26 + 26] = { { 0 } }; \
+ unibi_format(vars, vars + 26, str, data->params, out, ui, NULL, NULL); \
+ } \
+ } while (0)
static void unibi_out(UI *ui, int unibi_index)
{
- TUIData *data = ui->data;
-
- const char *str = NULL;
-
- if (unibi_index >= 0) {
- if (unibi_index < unibi_string_begin_) {
- str = unibi_get_ext_str(data->ut, (unsigned)unibi_index);
- } else {
- str = unibi_get_str(data->ut, (unsigned)unibi_index);
- }
- }
-
- if (str) {
- unibi_var_t vars[26 + 26] = {{0}};
- unibi_format(vars, vars + 26, str, data->params, out, ui, NULL, NULL);
- }
+ UNIBI_OUT(unibi_get_str);
+}
+static void unibi_out_ext(UI *ui, int unibi_index)
+{
+ UNIBI_OUT(unibi_get_ext_str);
}
+#undef UNIBI_OUT
static void out(void *ctx, const char *str, size_t len)
{
@@ -1261,7 +1263,9 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
bool gnome = terminfo_is_term_family(term, "gnome")
|| terminfo_is_term_family(term, "vte");
bool iterm = terminfo_is_term_family(term, "iterm")
- || terminfo_is_term_family(term, "iTerm.app");
+ || terminfo_is_term_family(term, "iterm2")
+ || terminfo_is_term_family(term, "iTerm.app")
+ || terminfo_is_term_family(term, "iTerm2.app");
// None of the following work over SSH; see :help TERM .
bool iterm_pretending_xterm = xterm && iterm_env;
bool konsole_pretending_xterm = xterm && konsole;
@@ -1533,7 +1537,9 @@ static void augment_terminfo(TUIData *data, const char *term,
bool screen = terminfo_is_term_family(term, "screen");
bool tmux = terminfo_is_term_family(term, "tmux") || !!os_getenv("TMUX");
bool iterm = terminfo_is_term_family(term, "iterm")
- || terminfo_is_term_family(term, "iTerm.app");
+ || terminfo_is_term_family(term, "iterm2")
+ || terminfo_is_term_family(term, "iTerm.app")
+ || terminfo_is_term_family(term, "iTerm2.app");
// None of the following work over SSH; see :help TERM .
bool iterm_pretending_xterm = xterm && iterm_env;
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 2a3fdbd70d..53b44f8029 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -272,7 +272,7 @@ static const int included_patches[] = {
// 683,
// 682,
// 681,
- // 680,
+ 680,
679,
678,
// 677,
@@ -340,7 +340,7 @@ static const int included_patches[] = {
// 615,
614,
// 613,
- // 612,
+ 612,
// 611,
// 610,
// 609,
@@ -515,7 +515,7 @@ static const int included_patches[] = {
// 440,
// 439,
// 438,
- // 437,
+ 437,
// 436,
// 435,
// 434,
@@ -626,8 +626,8 @@ static const int included_patches[] = {
// 329,
// 328,
// 327,
- // 326,
- // 325,
+ 326,
+ 325,
// 324,
// 323,
322,
@@ -644,7 +644,7 @@ static const int included_patches[] = {
311,
// 310,
// 309,
- // 308,
+ 308,
307,
// 306,
// 305,
@@ -860,7 +860,7 @@ static const int included_patches[] = {
// 95 NA
// 94 NA
// 93 NA
- // 92,
+ 92,
// 91,
90,
// 89 NA
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 081fc98816..c2d0a9b3b1 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -5515,11 +5515,14 @@ void restore_buffer(bufref_T *save_curbuf)
}
-// Add match to the match list of window 'wp'. The pattern 'pat' will be
-// highlighted with the group 'grp' with priority 'prio'.
-// Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
-// If no particular ID is desired, -1 must be specified for 'id'.
-// Return ID of added match, -1 on failure.
+/// Add match to the match list of window 'wp'. The pattern 'pat' will be
+/// highlighted with the group 'grp' with priority 'prio'.
+/// Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
+///
+/// @param[in] id a desired ID 'id' can be specified
+/// (greater than or equal to 1). -1 must be specified if no
+/// particular ID is desired
+/// @return ID of added match, -1 on failure.
int match_add(win_T *wp, const char *const grp, const char *const pat,
int prio, int id, list_T *pos_list,
const char *const conceal_char)
@@ -5697,10 +5700,9 @@ fail:
return -1;
}
-/*
- * Delete match with ID 'id' in the match list of window 'wp'.
- * Print error messages if 'perr' is TRUE.
- */
+
+/// Delete match with ID 'id' in the match list of window 'wp'.
+/// Print error messages if 'perr' is TRUE.
int match_delete(win_T *wp, int id, int perr)
{
matchitem_T *cur = wp->w_match_head;
diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua
index 6a32f979ea..9f245d913b 100644
--- a/test/functional/api/server_requests_spec.lua
+++ b/test/functional/api/server_requests_spec.lua
@@ -20,6 +20,22 @@ describe('server -> client', function()
cid = nvim('get_api_info')[1]
end)
+ it('handles unexpected closed stream while preparing RPC response', function()
+ source([[
+ let g:_nvim_args = [v:progpath, '--embed', '-n', '-u', 'NONE', '-i', 'NONE', ]
+ let ch1 = jobstart(g:_nvim_args, {'rpc': v:true})
+ let child1_ch = rpcrequest(ch1, "nvim_get_api_info")[0]
+ call rpcnotify(ch1, 'nvim_eval', 'rpcrequest('.child1_ch.', "nvim_get_api_info")')
+
+ let ch2 = jobstart(g:_nvim_args, {'rpc': v:true})
+ let child2_ch = rpcrequest(ch2, "nvim_get_api_info")[0]
+ call rpcnotify(ch2, 'nvim_eval', 'rpcrequest('.child2_ch.', "nvim_get_api_info")')
+
+ call jobstop(ch1)
+ ]])
+ eq(2, eval("1+1")) -- Still alive?
+ end)
+
describe('simple call', function()
it('works', function()
local function on_setup()
@@ -141,7 +157,7 @@ describe('server -> client', function()
end)
end)
- describe('when the client is a recursive vim instance', function()
+ describe('recursive (child) nvim client', function()
if os.getenv("TRAVIS") and helpers.os_name() == "osx" then
-- XXX: Hangs Travis macOS since e9061117a5b8f195c3f26a5cb94e18ddd7752d86.
pending("[Hangs on Travis macOS. #5002]", function() end)
@@ -155,7 +171,7 @@ describe('server -> client', function()
after_each(function() command('call rpcstop(vim)') end)
- it('can send/recieve notifications and make requests', function()
+ it('can send/receive notifications and make requests', function()
nvim('command', "call rpcnotify(vim, 'vim_set_current_line', 'SOME TEXT')")
-- Wait for the notification to complete.
@@ -188,7 +204,7 @@ describe('server -> client', function()
end)
end)
- describe('when using jobstart', function()
+ describe('jobstart()', function()
local jobid
before_each(function()
local channel = nvim('get_api_info')[1]
@@ -227,7 +243,7 @@ describe('server -> client', function()
end)
end)
- describe('when connecting to another nvim instance', function()
+ describe('connecting to another (peer) nvim', function()
local function connect_test(server, mode, address)
local serverpid = funcs.getpid()
local client = spawn(nvim_argv)
@@ -256,7 +272,7 @@ describe('server -> client', function()
client:close()
end
- it('over a named pipe', function()
+ it('via named pipe', function()
local server = spawn(nvim_argv)
set_session(server)
local address = funcs.serverlist()[1]
@@ -265,7 +281,7 @@ describe('server -> client', function()
connect_test(server, 'pipe', address)
end)
- it('to an ip adress', function()
+ it('via ip address', function()
local server = spawn(nvim_argv)
set_session(server)
local address = funcs.serverstart("127.0.0.1:")
@@ -273,7 +289,7 @@ describe('server -> client', function()
connect_test(server, 'tcp', address)
end)
- it('to a hostname', function()
+ it('via hostname', function()
local server = spawn(nvim_argv)
set_session(server)
local address = funcs.serverstart("localhost:")
diff --git a/test/functional/autocmd/termclose_spec.lua b/test/functional/autocmd/termclose_spec.lua
index 8cc49c0d4c..c6c30494dd 100644
--- a/test/functional/autocmd/termclose_spec.lua
+++ b/test/functional/autocmd/termclose_spec.lua
@@ -57,7 +57,9 @@ describe('TermClose event', function()
command('call jobstop(g:test_job)')
retry(nil, nil, function() eq(1, eval('get(g:, "test_job_exited", 0)')) end)
local duration = os.time() - start
- eq(4, duration)
+ -- nvim starts sending kill after 2*KILL_TIMEOUT_MS
+ helpers.ok(4 <= duration)
+ helpers.ok(duration <= 7) -- <= 4 + delta because of slow CI
end)
it('reports the correct <abuf>', function()
diff --git a/test/functional/clipboard/clipboard_provider_spec.lua b/test/functional/clipboard/clipboard_provider_spec.lua
index e6544a8e2e..f66fbf7c94 100644
--- a/test/functional/clipboard/clipboard_provider_spec.lua
+++ b/test/functional/clipboard/clipboard_provider_spec.lua
@@ -90,8 +90,9 @@ describe('clipboard', function()
basic_register_test()
end)
- it('`:redir @+>` with invalid g:clipboard shows error exactly once', function()
- local screen = Screen.new(72, 5)
+ it('`:redir @+>` with invalid g:clipboard shows exactly one error #7184',
+ function()
+ local screen = Screen.new(72, 4)
screen:attach()
command("let g:clipboard = 'bogus'")
feed_command('redir @+> | :silent echo system("cat CONTRIBUTING.md") | redir END')
@@ -99,15 +100,40 @@ describe('clipboard', function()
^ |
~ |
~ |
+ clipboard: No provider. Try ":CheckHealth" or ":h clipboard". |
+ ]], nil, {{bold = true, foreground = Screen.colors.Blue}})
+ end)
+
+ it('`:redir @+>|bogus_cmd|redir END` + invalid g:clipboard must not recurse #7184',
+ function()
+ local screen = Screen.new(72, 4)
+ screen:attach()
+ command("let g:clipboard = 'bogus'")
+ feed_command('redir @+> | bogus_cmd | redir END')
+ screen:expect([[
~ |
clipboard: No provider. Try ":CheckHealth" or ":h clipboard". |
+ E492: Not an editor command: bogus_cmd | redir END |
+ Press ENTER or type command to continue^ |
]], nil, {{bold = true, foreground = Screen.colors.Blue}})
end)
- it('invalid g:clipboard', function()
+ it('invalid g:clipboard shows hint if :redir is not active', function()
command("let g:clipboard = 'bogus'")
eq('', eval('provider#clipboard#Executable()'))
eq('clipboard: invalid g:clipboard', eval('provider#clipboard#Error()'))
+
+ local screen = Screen.new(72, 4)
+ screen:attach()
+ command("let g:clipboard = 'bogus'")
+ -- Explicit clipboard attempt, should show a hint message.
+ feed_command('let @+="foo"')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ clipboard: No provider. Try ":CheckHealth" or ":h clipboard". |
+ ]], nil, {{bold = true, foreground = Screen.colors.Blue}})
end)
it('valid g:clipboard', function()
@@ -148,6 +174,19 @@ describe('clipboard', function()
eq(0, eval("g:clip_called_set"))
end)
+ it('`:redir @+>|bogus_cmd|redir END` must not recurse #7184',
+ function()
+ local screen = Screen.new(72, 4)
+ screen:attach()
+ feed_command('redir @+> | bogus_cmd | redir END')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ E492: Not an editor command: bogus_cmd | redir END |
+ ]], nil, {{bold = true, foreground = Screen.colors.Blue}})
+ end)
+
it('has independent "* and unnamed registers by default', function()
insert("some words")
feed('^"*dwdw"*P')
diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua
index 54e56f7f41..1b8a5b1b95 100644
--- a/test/functional/core/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -677,12 +677,12 @@ describe("pty process teardown", function()
-- Exiting should terminate all descendants (PTY, its children, ...).
screen:expect([[
- |
+ ^ |
[Process exited 0] |
|
|
|
- -- TERMINAL -- |
+ |
]])
end)
end)
diff --git a/test/functional/legacy/003_cindent_spec.lua b/test/functional/legacy/003_cindent_spec.lua
index 27835fea28..0cc4d298b7 100644
--- a/test/functional/legacy/003_cindent_spec.lua
+++ b/test/functional/legacy/003_cindent_spec.lua
@@ -3915,6 +3915,26 @@ describe('cindent', function()
{
111111111111111111;
}
+ namespace test::cpp17
+ {
+ 111111111111111111;
+ }
+ namespace ::incorrectcpp17
+ {
+ 111111111111111111;
+ }
+ namespace test::incorrectcpp17::
+ {
+ 111111111111111111;
+ }
+ namespace test:incorrectcpp17
+ {
+ 111111111111111111;
+ }
+ namespace test:::incorrectcpp17
+ {
+ 111111111111111111;
+ }
namespace{
111111111111111111;
}
@@ -3986,6 +4006,26 @@ describe('cindent', function()
{
111111111111111111;
}
+ namespace test::cpp17
+ {
+ 111111111111111111;
+ }
+ namespace ::incorrectcpp17
+ {
+ 111111111111111111;
+ }
+ namespace test::incorrectcpp17::
+ {
+ 111111111111111111;
+ }
+ namespace test:incorrectcpp17
+ {
+ 111111111111111111;
+ }
+ namespace test:::incorrectcpp17
+ {
+ 111111111111111111;
+ }
namespace{
111111111111111111;
}
diff --git a/test/functional/legacy/051_highlight_spec.lua b/test/functional/legacy/051_highlight_spec.lua
index 60d29246ff..2ef74196ee 100644
--- a/test/functional/legacy/051_highlight_spec.lua
+++ b/test/functional/legacy/051_highlight_spec.lua
@@ -37,6 +37,7 @@ describe(':highlight', function()
feed('q')
wait() -- wait until we're back to normal
command('hi Search')
+ command('hi Normal')
-- Test setting colors.
-- Test clearing one color and all doesn't generate error or warning
diff --git a/test/functional/legacy/packadd_spec.lua b/test/functional/legacy/packadd_spec.lua
index c280888dda..7c44353aec 100644
--- a/test/functional/legacy/packadd_spec.lua
+++ b/test/functional/legacy/packadd_spec.lua
@@ -83,6 +83,41 @@ describe('packadd', function()
call assert_equal(new_rtp, &rtp)
endfunc
+ func Test_packadd_symlink_dir()
+ if !has('unix')
+ return
+ endif
+ let top2_dir = s:topdir . '/Xdir2'
+ let real_dir = s:topdir . '/Xsym'
+ call mkdir(real_dir, 'p')
+ exec "silent! !ln -s Xsym" top2_dir
+ let &rtp = top2_dir . ',' . top2_dir . '/after'
+ let &packpath = &rtp
+
+ let s:plugdir = top2_dir . '/pack/mine/opt/mytest'
+ call mkdir(s:plugdir . '/plugin', 'p')
+
+ exe 'split ' . s:plugdir . '/plugin/test.vim'
+ call setline(1, 'let g:plugin_works = 44')
+ wq
+ let g:plugin_works = 0
+
+ packadd mytest
+
+ " Must have been inserted in the middle, not at the end
+ call assert_true(&rtp =~ '/pack/mine/opt/mytest,')
+ call assert_equal(44, g:plugin_works)
+
+ " No change when doing it again.
+ let rtp_before = &rtp
+ packadd mytest
+ call assert_equal(rtp_before, &rtp)
+
+ set rtp&
+ let rtp = &rtp
+ exec "silent !rm" top2_dir
+ endfunc
+
func Test_packloadall()
" plugin foo with an autoload directory
let fooplugindir = &packpath . '/pack/mine/start/foo/plugin'
@@ -227,6 +262,11 @@ describe('packadd', function()
expected_empty()
end)
+ it('works with symlinks', function()
+ call('Test_packadd_symlink_dir')
+ expected_empty()
+ end)
+
it('works with :packloadall', function()
call('Test_packloadall')
expected_empty()
diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua
index 9930efc402..7522f073c4 100644
--- a/test/functional/terminal/ex_terminal_spec.lua
+++ b/test/functional/terminal/ex_terminal_spec.lua
@@ -72,10 +72,10 @@ describe(':terminal (with fake shell)', function()
terminal_with_fake_shell()
wait()
screen:expect([[
- ready $ |
+ ^ready $ |
[Process exited 0] |
|
- -- TERMINAL -- |
+ :terminal |
]])
end)
@@ -96,10 +96,10 @@ describe(':terminal (with fake shell)', function()
terminal_with_fake_shell()
wait()
screen:expect([[
- jeff $ |
+ ^jeff $ |
[Process exited 0] |
|
- -- TERMINAL -- |
+ :terminal |
]])
end)
@@ -107,10 +107,10 @@ describe(':terminal (with fake shell)', function()
terminal_with_fake_shell('echo hi')
wait()
screen:expect([[
- ready $ echo hi |
+ ^ready $ echo hi |
|
[Process exited 0] |
- -- TERMINAL -- |
+ :terminal echo hi |
]])
end)
@@ -119,10 +119,10 @@ describe(':terminal (with fake shell)', function()
terminal_with_fake_shell('echo hi')
wait()
screen:expect([[
- jeff $ echo hi |
+ ^jeff $ echo hi |
|
[Process exited 0] |
- -- TERMINAL -- |
+ :terminal echo hi |
]])
end)
@@ -130,10 +130,10 @@ describe(':terminal (with fake shell)', function()
terminal_with_fake_shell([[echo 'hello' \ "world"]])
wait()
screen:expect([[
- ready $ echo 'hello' \ "world" |
+ ^ready $ echo 'hello' \ "world" |
|
[Process exited 0] |
- -- TERMINAL -- |
+ :terminal echo 'hello' \ "world" |
]])
end)
@@ -166,10 +166,10 @@ describe(':terminal (with fake shell)', function()
terminal_with_fake_shell()
wait()
screen:expect([[
- ready $ |
+ ^ready $ |
[Process exited 0] |
|
- -- TERMINAL -- |
+ :terminal |
]])
eq('term://', string.match(eval('bufname("%")'), "^term://"))
helpers.feed([[<C-\><C-N>]])
@@ -184,10 +184,10 @@ describe(':terminal (with fake shell)', function()
it('works with gf', function()
terminal_with_fake_shell([[echo "scripts/shadacat.py"]])
screen:expect([[
- ready $ echo "scripts/shadacat.py" |
+ ^ready $ echo "scripts/shadacat.py" |
|
[Process exited 0] |
- -- TERMINAL -- |
+ :terminal echo "scripts/shadacat.py" |
]])
helpers.feed([[<C-\><C-N>]])
eq('term://', string.match(eval('bufname("%")'), "^term://"))
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index 21b907c8f7..34a5ac0a49 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -287,8 +287,8 @@ describe('tui focus event handling', function()
feed_data(':terminal\n')
feed_data('\027[I')
screen:expect([[
- ready $ |
- [Process exited 0]{1: } |
+ {1:r}eady $ |
+ [Process exited 0] |
|
|
|
@@ -297,8 +297,8 @@ describe('tui focus event handling', function()
]])
feed_data('\027[O')
screen:expect([[
- ready $ |
- [Process exited 0]{1: } |
+ {1:r}eady $ |
+ [Process exited 0] |
|
|
|