aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/options.txt15
-rw-r--r--src/nvim/CMakeLists.txt4
-rw-r--r--src/nvim/buffer.c2
-rw-r--r--src/nvim/event/process.c22
-rw-r--r--src/nvim/event/process.h3
-rw-r--r--src/nvim/ex_cmds.c13
-rw-r--r--src/nvim/getchar.c4
-rw-r--r--src/nvim/globals.h2
-rw-r--r--src/nvim/mbyte.c6
-rw-r--r--src/nvim/msgpack_rpc/server.h2
-rw-r--r--src/nvim/os/shell.h2
-rw-r--r--src/nvim/regexp.c95
-rw-r--r--src/nvim/regexp_nfa.c13
-rw-r--r--src/nvim/strings.c82
-rw-r--r--src/nvim/terminal.c10
15 files changed, 108 insertions, 167 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 34c86c3fb0..afc7c20ed5 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -3129,7 +3129,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|hl-SpecialKey| 8 Meta and special keys listed with ":map"
|hl-Whitespace| 0
|hl-EndOfBuffer| ~ lines after the last line in the buffer
- |hl-NormalNC| I inactive (not the current) window
+ |hl-NormalNC| I non-current ("inactive") window
|hl-TermCursor| z Cursor in a focused terminal
|hl-TermCursorNC| Z Cursor in an unfocused terminal
|hl-NonText| @ '@' at the end of the window and
@@ -6847,12 +6847,13 @@ A jump table for the options with a short description can be found at |Q_op|.
*'winhighlight'* *'winhl'*
'winhighlight' 'winhl' string (default empty)
local to window
- Highlight groups specific to a window. It consists of items that must
- be separated by a comma, each item is a global builtin highlight group
- and a highlight group overidding it for this window, separated by a
- colon. Currently only |hl-Normal| and |hl-NormalNC| can be overriden;
- this is mostly useful for changing the background color. Example: >
- set winhighlight=Normal:MyBackground,NormalNC:MyBackgroundNC
+ Window-local highlights. Comma-delimited list of |group-name| pairs
+ "{hl-builtin}:{hl-group},..." where each {hl-builtin} is a group (from
+ |highlight-groups|) to be overridden by {hl-group} in the window where
+ this option was set.
+ Currently |hl-Normal| and |hl-NormalNC| can be overridden.
+ Useful for changing the background color. Example: >
+ set winhighlight=Normal:MyNormal,NormalNC:MyNormalNC
<
*'winfixheight'* *'wfh'* *'nowinfixheight'* *'nowfh'*
'winfixheight' 'wfh' boolean (default off)
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 170dd16b02..f69781a539 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -429,10 +429,6 @@ function(get_test_target prefix sfile relative_path_var target_var)
endfunction()
set(NO_SINGLE_CHECK_HEADERS
- misc2.h
- msgpack_rpc/server.h
- os/shell.h
- os_unix.h
os/win_defs.h
regexp_defs.h
syntax_defs.h
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index ebe50c6d31..4ed75d8a2d 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -449,7 +449,7 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
if (buf->terminal) {
terminal_close(buf->terminal, NULL);
- }
+ }
/* Always remove the buffer when there is no file name. */
if (buf->b_ffname == NULL)
diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
index 6aab7d903c..ffda10a494 100644
--- a/src/nvim/event/process.c
+++ b/src/nvim/event/process.c
@@ -20,9 +20,9 @@
# include "event/process.c.generated.h"
#endif
-// Time for a process to exit cleanly before we send KILL.
-#define KILL_TIMEOUT_MS 2000
-#define KILL_TIMEOUT_NS (KILL_TIMEOUT_MS * 1000000)
+// Time (ns) for a process to exit cleanly before we send TERM/KILL.
+#define TERM_TIMEOUT 1000000000
+#define KILL_TIMEOUT (TERM_TIMEOUT * 2)
#define CLOSE_PROC_STREAM(proc, stream) \
do { \
@@ -121,6 +121,8 @@ void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL
// Close handles to process without killing it.
CREATE_EVENT(loop->events, process_close_handles, 1, proc);
} else {
+ uv_kill(proc->pid, SIGTERM);
+ proc->term_sent = true;
process_stop(proc);
}
}
@@ -242,16 +244,12 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL
abort();
}
- ILOG("Sending SIGTERM to pid %d", proc->pid);
- uv_kill(proc->pid, SIGTERM);
-
Loop *loop = proc->loop;
if (!loop->children_stop_requests++) {
// When there's at least one stop request pending, start a timer that
- // will periodically check if a signal should be send to the job.
+ // will periodically check if a signal should be send to a to the job
DLOG("Starting job kill timer");
- uv_timer_start(&loop->children_kill_timer, children_kill_cb,
- KILL_TIMEOUT_MS, 100);
+ uv_timer_start(&loop->children_kill_timer, children_kill_cb, 100, 100);
}
}
@@ -269,7 +267,11 @@ static void children_kill_cb(uv_timer_t *handle)
}
uint64_t elapsed = now - proc->stopped_time;
- if (elapsed >= KILL_TIMEOUT_NS) {
+ if (!proc->term_sent && elapsed >= TERM_TIMEOUT) {
+ ILOG("Sending SIGTERM to pid %d", proc->pid);
+ uv_kill(proc->pid, SIGTERM);
+ proc->term_sent = true;
+ } else if (elapsed >= KILL_TIMEOUT) {
ILOG("Sending SIGKILL to pid %d", proc->pid);
uv_kill(proc->pid, SIGKILL);
}
diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h
index 5c00e8e7ec..26d70a5e6d 100644
--- a/src/nvim/event/process.h
+++ b/src/nvim/event/process.h
@@ -26,7 +26,7 @@ struct process {
Stream *in, *out, *err;
process_exit_cb cb;
internal_process_cb internal_exit_cb, internal_close_cb;
- bool closed, detach;
+ bool closed, term_sent, detach;
MultiQueue *events;
};
@@ -48,6 +48,7 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data)
.err = NULL,
.cb = NULL,
.closed = false,
+ .term_sent = false,
.internal_close_cb = NULL,
.internal_exit_cb = NULL,
.detach = false
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index f73d4c16b6..018a228843 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -5101,14 +5101,13 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname,
}
p1 = vim_strchr(IObuff, '*'); /* find first '*' */
while (p1 != NULL) {
- /* Use vim_strbyte() instead of vim_strchr() so that when
- * 'encoding' is dbcs it still works, don't find '*' in the
- * second byte. */
- p2 = vim_strbyte(p1 + 1, '*'); /* find second '*' */
- if (p2 != NULL && p2 > p1 + 1) { /* skip "*" and "**" */
- for (s = p1 + 1; s < p2; ++s)
- if (*s == ' ' || *s == '\t' || *s == '|')
+ p2 = (char_u *)strchr((const char *)p1 + 1, '*'); // Find second '*'.
+ if (p2 != NULL && p2 > p1 + 1) { // Skip "*" and "**".
+ for (s = p1 + 1; s < p2; s++) {
+ if (*s == ' ' || *s == '\t' || *s == '|') {
break;
+ }
+ }
/*
* Only accept a *tag* when it consists of valid
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 6e21ee96e8..79b95272de 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -3596,8 +3596,8 @@ int check_abbr(int c, char_u *ptr, int col, int mincol)
char_u *q = mp->m_keys;
int match;
- if (vim_strbyte(mp->m_keys, K_SPECIAL) != NULL) {
- /* might have CSI escaped mp->m_keys */
+ if (strchr((const char *)mp->m_keys, K_SPECIAL) != NULL) {
+ // Might have CSI escaped mp->m_keys.
q = vim_strsave(mp->m_keys);
vim_unescape_csi(q);
qlen = (int)STRLEN(q);
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index c7985d6a65..b820965680 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -465,7 +465,7 @@ typedef enum {
, HLF_MC // 'colorcolumn'
, HLF_QFL // selected quickfix line
, HLF_0 // Whitespace
- , HLF_INACTIVE // Inactive window
+ , HLF_INACTIVE // NormalNC: Normal text in non-current windows
, HLF_COUNT // MUST be the last one
} hlf_T;
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 8a68ce0915..d5907da2ed 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -359,10 +359,10 @@ int bomb_size(void)
*/
void remove_bom(char_u *s)
{
- char_u *p = s;
+ char *p = (char *)s;
- while ((p = vim_strbyte(p, 0xef)) != NULL) {
- if (p[1] == 0xbb && p[2] == 0xbf) {
+ while ((p = strchr(p, 0xef)) != NULL) {
+ if ((uint8_t)p[1] == 0xbb && (uint8_t)p[2] == 0xbf) {
STRMOVE(p, p + 3);
} else {
p++;
diff --git a/src/nvim/msgpack_rpc/server.h b/src/nvim/msgpack_rpc/server.h
index f1a6703938..5446e40e0b 100644
--- a/src/nvim/msgpack_rpc/server.h
+++ b/src/nvim/msgpack_rpc/server.h
@@ -1,6 +1,8 @@
#ifndef NVIM_MSGPACK_RPC_SERVER_H
#define NVIM_MSGPACK_RPC_SERVER_H
+#include <stdio.h>
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "msgpack_rpc/server.h.generated.h"
#endif
diff --git a/src/nvim/os/shell.h b/src/nvim/os/shell.h
index 58960db157..48503f2601 100644
--- a/src/nvim/os/shell.h
+++ b/src/nvim/os/shell.h
@@ -1,6 +1,8 @@
#ifndef NVIM_OS_SHELL_H
#define NVIM_OS_SHELL_H
+#include <stdio.h>
+
#include "nvim/types.h"
// Flags for os_call_shell() second argument
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index 7a00ee27bb..5448cc7131 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -3427,32 +3427,26 @@ static long bt_regexec_both(char_u *line,
c = *prog->regmust;
s = line + col;
- /*
- * This is used very often, esp. for ":global". Use three versions of
- * the loop to avoid overhead of conditions.
- */
- if (!ireg_ic
- && !has_mbyte
- )
- while ((s = vim_strbyte(s, c)) != NULL) {
- if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0)
- break; /* Found it. */
- ++s;
- }
- else if (!ireg_ic || (!enc_utf8 && mb_char2len(c) > 1))
+ // This is used very often, esp. for ":global". Use two versions of
+ // the loop to avoid overhead of conditions.
+ if (!ireg_ic) {
while ((s = vim_strchr(s, c)) != NULL) {
- if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0)
- break; /* Found it. */
+ if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0) {
+ break; // Found it.
+ }
mb_ptr_adv(s);
}
- else
+ } else {
while ((s = cstrchr(s, c)) != NULL) {
- if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0)
- break; /* Found it. */
+ if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0) {
+ break; // Found it.
+ }
mb_ptr_adv(s);
}
- if (s == NULL) /* Not present. */
+ }
+ if (s == NULL) { // Not present.
goto theend;
+ }
}
regline = line;
@@ -3482,14 +3476,8 @@ static long bt_regexec_both(char_u *line,
/* Messy cases: unanchored match. */
while (!got_int) {
if (prog->regstart != NUL) {
- /* Skip until the char we know it must start with.
- * Used often, do some work to avoid call overhead. */
- if (!ireg_ic
- && !has_mbyte
- )
- s = vim_strbyte(regline + col, prog->regstart);
- else
- s = cstrchr(regline + col, prog->regstart);
+ // Skip until the char we know it must start with.
+ s = cstrchr(regline + col, prog->regstart);
if (s == NULL) {
retval = 0;
break;
@@ -6299,44 +6287,37 @@ static int cstrncmp(char_u *s1, char_u *s2, int *n)
/*
* cstrchr: This function is used a lot for simple searches, keep it fast!
*/
-static char_u *cstrchr(char_u *s, int c)
+static inline char_u *cstrchr(const char_u *const s, const int c)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_ALWAYS_INLINE
{
- char_u *p;
- int cc;
-
- if (!ireg_ic
- || (!enc_utf8 && mb_char2len(c) > 1)
- )
+ if (!ireg_ic) {
return vim_strchr(s, c);
+ }
- /* tolower() and toupper() can be slow, comparing twice should be a lot
- * faster (esp. when using MS Visual C++!).
- * For UTF-8 need to use folded case. */
+ // Use folded case for UTF-8, slow! For ASCII use libc strpbrk which is
+ // expected to be highly optimized.
if (c > 0x80) {
- cc = utf_fold(c);
- } else if (mb_isupper(c)) {
- cc = mb_tolower(c);
- } else if (mb_islower(c)) {
- cc = mb_toupper(c);
+ const int folded_c = utf_fold(c);
+ for (const char_u *p = s; *p != NUL; p += utfc_ptr2len(p)) {
+ if (utf_fold(utf_ptr2char(p)) == folded_c) {
+ return (char_u *)p;
+ }
+ }
+ return NULL;
+ }
+
+ int cc;
+ if (ASCII_ISUPPER(c)) {
+ cc = TOLOWER_ASC(c);
+ } else if (ASCII_ISLOWER(c)) {
+ cc = TOUPPER_ASC(c);
} else {
return vim_strchr(s, c);
}
- if (has_mbyte) {
- for (p = s; *p != NUL; p += (*mb_ptr2len)(p)) {
- if (enc_utf8 && c > 0x80) {
- if (utf_fold(utf_ptr2char(p)) == cc)
- return p;
- } else if (*p == c || *p == cc)
- return p;
- }
- } else
- /* Faster version for when there are no multi-byte characters. */
- for (p = s; *p != NUL; ++p)
- if (*p == c || *p == cc)
- return p;
-
- return NULL;
+ char tofind[] = { (char)c, (char)cc, NUL };
+ return (char_u *)strpbrk((const char *)s, tofind);
}
/***************************************************************
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
index 139772d51e..85fae9d82e 100644
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.c
@@ -4855,17 +4855,10 @@ static int failure_chance(nfa_state_T *state, int depth)
*/
static int skip_to_start(int c, colnr_T *colp)
{
- char_u *s;
-
- /* Used often, do some work to avoid call overhead. */
- if (!ireg_ic
- && !has_mbyte
- )
- s = vim_strbyte(regline + *colp, c);
- else
- s = cstrchr(regline + *colp, c);
- if (s == NULL)
+ const char_u *const s = cstrchr(regline + *colp, c);
+ if (s == NULL) {
return FAIL;
+ }
*colp = (int)(s - regline);
return OK;
}
diff --git a/src/nvim/strings.c b/src/nvim/strings.c
index 743b43c2e5..f19cf7a261 100644
--- a/src/nvim/strings.c
+++ b/src/nvim/strings.c
@@ -425,72 +425,28 @@ int vim_strnicmp(const char *s1, const char *s2, size_t len)
}
#endif
-/*
- * Version of strchr() and strrchr() that handle unsigned char strings
- * with characters from 128 to 255 correctly. It also doesn't return a
- * pointer to the NUL at the end of the string.
- */
-char_u *vim_strchr(const char_u *string, int c)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
+/// strchr() version which handles multibyte strings
+///
+/// @param[in] string String to search in.
+/// @param[in] c Character to search for. Must be a valid character.
+///
+/// @return Pointer to the first byte of the found character in string or NULL
+/// if it was not found. NUL character is never found, use `strlen()`
+/// instead.
+char_u *vim_strchr(const char_u *const string, const int c)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- int b;
-
- const char_u *p = string;
- if (enc_utf8 && c >= 0x80) {
- while (*p != NUL) {
- int l = (*mb_ptr2len)(p);
-
- // Avoid matching an illegal byte here.
- if (l > 1 && utf_ptr2char(p) == c) {
- return (char_u *) p;
- }
- p += l;
- }
+ assert(c >= 0);
+ if (c == 0) {
return NULL;
+ } else if (c < 0x80) {
+ return (char_u *)strchr((const char *)string, c);
+ } else {
+ char u8char[MB_MAXBYTES + 1];
+ const int len = utf_char2bytes(c, (char_u *)u8char);
+ u8char[len] = NUL;
+ return (char_u *)strstr((const char *)string, u8char);
}
- if (enc_dbcs != 0 && c > 255) {
- int n2 = c & 0xff;
-
- c = ((unsigned)c >> 8) & 0xff;
- while ((b = *p) != NUL) {
- if (b == c && p[1] == n2)
- return (char_u *) p;
- p += (*mb_ptr2len)(p);
- }
- return NULL;
- }
- if (has_mbyte) {
- while ((b = *p) != NUL) {
- if (b == c)
- return (char_u *) p;
- p += (*mb_ptr2len)(p);
- }
- return NULL;
- }
- while ((b = *p) != NUL) {
- if (b == c)
- return (char_u *) p;
- ++p;
- }
- return NULL;
-}
-
-/*
- * Version of strchr() that only works for bytes and handles unsigned char
- * strings with characters above 128 correctly. It also doesn't return a
- * pointer to the NUL at the end of the string.
- */
-char_u *vim_strbyte(const char_u *string, int c)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
-{
- const char_u *p = string;
-
- while (*p != NUL) {
- if (*p == c)
- return (char_u *) p;
- ++p;
- }
- return NULL;
}
/*
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index c44fe15be5..cc1de583d3 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -302,8 +302,16 @@ void terminal_close(Terminal *term, char *msg)
}
term->forward_mouse = false;
- term->closed = true;
+
+ // flush any pending changes to the buffer
+ if (!exiting) {
+ block_autocmds();
+ refresh_terminal(term);
+ unblock_autocmds();
+ }
+
buf_T *buf = handle_get_buffer(term->buf_handle);
+ term->closed = true;
if (!msg || exiting) {
// If no msg was given, this was called by close_buffer(buffer.c). Or if