diff options
-rw-r--r-- | runtime/doc/options.txt | 15 | ||||
-rw-r--r-- | src/nvim/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/nvim/buffer.c | 2 | ||||
-rw-r--r-- | src/nvim/event/process.c | 22 | ||||
-rw-r--r-- | src/nvim/event/process.h | 3 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 13 | ||||
-rw-r--r-- | src/nvim/getchar.c | 4 | ||||
-rw-r--r-- | src/nvim/globals.h | 2 | ||||
-rw-r--r-- | src/nvim/mbyte.c | 6 | ||||
-rw-r--r-- | src/nvim/msgpack_rpc/server.h | 2 | ||||
-rw-r--r-- | src/nvim/os/shell.h | 2 | ||||
-rw-r--r-- | src/nvim/regexp.c | 95 | ||||
-rw-r--r-- | src/nvim/regexp_nfa.c | 13 | ||||
-rw-r--r-- | src/nvim/strings.c | 82 | ||||
-rw-r--r-- | src/nvim/terminal.c | 10 |
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 |