diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/edit.c | 83 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 2 | ||||
-rw-r--r-- | src/nvim/fileio.c | 48 | ||||
-rw-r--r-- | src/nvim/keymap.c | 32 | ||||
-rw-r--r-- | src/nvim/normal.c | 6 | ||||
-rw-r--r-- | src/nvim/os/fs.c | 4 | ||||
-rw-r--r-- | src/nvim/os/os_defs.h | 19 | ||||
-rw-r--r-- | src/nvim/os/shell.c | 25 | ||||
-rw-r--r-- | src/nvim/os/unix_defs.h | 12 | ||||
-rw-r--r-- | src/nvim/os/win_defs.h | 5 | ||||
-rw-r--r-- | src/nvim/os_unix.c | 4 | ||||
-rw-r--r-- | src/nvim/strings.c | 48 | ||||
-rw-r--r-- | src/nvim/terminal.c | 26 |
13 files changed, 149 insertions, 165 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c index b3222b0781..ccfc9b4803 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1352,24 +1352,21 @@ ins_redraw ( if (char_avail()) return; - /* Trigger CursorMoved if the cursor moved. Not when the popup menu is - * visible, the command might delete it. */ - if (ready && ( - has_cursormovedI() - || - curwin->w_p_cole > 0 - ) + // Trigger CursorMoved if the cursor moved. Not when the popup menu is + // visible, the command might delete it. + if (ready && (has_event(EVENT_CURSORMOVEDI) || curwin->w_p_cole > 0) && !equalpos(last_cursormoved, curwin->w_cursor) - && !pum_visible() - ) { - /* Need to update the screen first, to make sure syntax - * highlighting is correct after making a change (e.g., inserting - * a "(". The autocommand may also require a redraw, so it's done - * again below, unfortunately. */ - if (syntax_present(curwin) && must_redraw) + && !pum_visible()) { + // Need to update the screen first, to make sure syntax + // highlighting is correct after making a change (e.g., inserting + // a "(". The autocommand may also require a redraw, so it's done + // again below, unfortunately. + if (syntax_present(curwin) && must_redraw) { update_screen(0); - if (has_cursormovedI()) - apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, FALSE, curbuf); + } + if (has_event(EVENT_CURSORMOVEDI)) { + apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, false, curbuf); + } if (curwin->w_p_cole > 0) { conceal_old_cursor_line = last_cursormoved.lnum; conceal_new_cursor_line = curwin->w_cursor.lnum; @@ -1378,13 +1375,13 @@ ins_redraw ( last_cursormoved = curwin->w_cursor; } - /* Trigger TextChangedI if b_changedtick differs. */ - if (ready && has_textchangedI() + // Trigger TextChangedI if b_changedtick differs. + if (ready && has_event(EVENT_TEXTCHANGEDI) && last_changedtick != curbuf->b_changedtick - && !pum_visible() - ) { - if (last_changedtick_buf == curbuf) - apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf); + && !pum_visible()) { + if (last_changedtick_buf == curbuf) { + apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, false, curbuf); + } last_changedtick_buf = curbuf; last_changedtick = curbuf->b_changedtick; } @@ -5124,24 +5121,20 @@ insertchar ( can_si = FALSE; can_si_back = FALSE; - /* - * If there's any pending input, grab up to INPUT_BUFLEN at once. - * This speeds up normal text input considerably. - * Don't do this when 'cindent' or 'indentexpr' is set, because we might - * need to re-indent at a ':', or any other character (but not what - * 'paste' is set).. - * Don't do this when there an InsertCharPre autocommand is defined, - * because we need to fire the event for every character. - */ - - if ( !ISSPECIAL(c) - && (!has_mbyte || (*mb_char2len)(c) == 1) - && vpeekc() != NUL - && !(State & REPLACE_FLAG) - && !cindent_on() - && !p_ri - && !has_insertcharpre() - ) { + // If there's any pending input, grab up to INPUT_BUFLEN at once. + // This speeds up normal text input considerably. + // Don't do this when 'cindent' or 'indentexpr' is set, because we might + // need to re-indent at a ':', or any other character (but not what + // 'paste' is set).. + // Don't do this when there an InsertCharPre autocommand is defined, + // because we need to fire the event for every character. + if (!ISSPECIAL(c) + && (!has_mbyte || (*mb_char2len)(c) == 1) + && vpeekc() != NUL + && !(State & REPLACE_FLAG) + && !cindent_on() + && !p_ri + && !has_event(EVENT_INSERTCHARPRE)) { #define INPUT_BUFLEN 100 char_u buf[INPUT_BUFLEN + 1]; int i; @@ -8486,13 +8479,13 @@ static char_u *do_insert_char_pre(int c) { char_u buf[MB_MAXBYTES + 1]; - /* Return quickly when there is nothing to do. */ - if (!has_insertcharpre()) + // Return quickly when there is nothing to do. + if (!has_event(EVENT_INSERTCHARPRE)) { return NULL; - - if (has_mbyte) + } + if (has_mbyte) { buf[(*mb_char2bytes)(c, buf)] = NUL; - else { + } else { buf[0] = c; buf[1] = NUL; } diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index fad497928c..84bd31d9ad 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1694,7 +1694,7 @@ static char_u * do_one_cmd(char_u **cmdlinep, // autocommands defined, trigger the matching autocommands. if (p != NULL && ea.cmdidx == CMD_SIZE && !ea.skip && ASCII_ISUPPER(*ea.cmd) - && has_cmdundefined()) { + && has_event(EVENT_CMDUNDEFINED)) { p = ea.cmd; while (ASCII_ISALNUM(*p)) { ++p; diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 05cb8f8f8c..bd0f0fc80a 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -6266,50 +6266,12 @@ int trigger_cursorhold(void) return FALSE; } -/* - * Return TRUE when there is a CursorMoved autocommand defined. - */ -int has_cursormoved(void) -{ - return first_autopat[(int)EVENT_CURSORMOVED] != NULL; -} - -/* - * Return TRUE when there is a CursorMovedI autocommand defined. - */ -int has_cursormovedI(void) -{ - return first_autopat[(int)EVENT_CURSORMOVEDI] != NULL; -} - -/* - * Return TRUE when there is a TextChanged autocommand defined. - */ -int has_textchanged(void) -{ - return first_autopat[(int)EVENT_TEXTCHANGED] != NULL; -} - -/* - * Return TRUE when there is a TextChangedI autocommand defined. - */ -int has_textchangedI(void) -{ - return first_autopat[(int)EVENT_TEXTCHANGEDI] != NULL; -} - -/* - * Return TRUE when there is an InsertCharPre autocommand defined. - */ -int has_insertcharpre(void) -{ - return first_autopat[(int)EVENT_INSERTCHARPRE] != NULL; -} - -/// @returns true when there is an CmdUndefined autocommand defined. -int has_cmdundefined(void) +/// Return true if "event" autocommand is defined. +/// +/// @param event the autocommand to check +bool has_event(int event) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { - return first_autopat[(int)EVENT_CMDUNDEFINED] != NULL; + return first_autopat[event] != NULL; } static int diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c index 04d6cbf5e3..b2fd929714 100644 --- a/src/nvim/keymap.c +++ b/src/nvim/keymap.c @@ -18,6 +18,9 @@ #include "nvim/strings.h" #include "nvim/mouse.h" +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "keymap.c.generated.h" +#endif /* * Some useful tables. @@ -637,11 +640,11 @@ find_special_key ( key = DEL; } - /* - * Normal Key with modifier: Try to make a single byte code. - */ - if (!IS_SPECIAL(key)) + // Normal Key with modifier: + // Try to make a single byte code (except for Alt/Meta modifiers). + if (!IS_SPECIAL(key)) { key = extract_modifiers(key, &modifiers); + } *modp = modifiers; *srcp = end_of_name; @@ -652,11 +655,9 @@ find_special_key ( return 0; } -/* - * Try to include modifiers in the key. - * Changes "Shift-a" to 'A', "Alt-A" to 0xc0, etc. - */ -int extract_modifiers(int key, int *modp) +/// Try to include modifiers (except alt/meta) in the key. +/// Changes "Shift-a" to 'A', "Ctrl-@" to <Nul>, etc. +static int extract_modifiers(int key, int *modp) { int modifiers = *modp; @@ -665,19 +666,12 @@ int extract_modifiers(int key, int *modp) modifiers &= ~MOD_MASK_SHIFT; } if ((modifiers & MOD_MASK_CTRL) - && ((key >= '?' && key <= '_') || ASCII_ISALPHA(key)) - ) { + && ((key >= '?' && key <= '_') || ASCII_ISALPHA(key))) { key = Ctrl_chr(key); modifiers &= ~MOD_MASK_CTRL; - /* <C-@> is <Nul> */ - if (key == 0) + if (key == 0) { // <C-@> is <Nul> key = K_ZERO; - } - if ((modifiers & MOD_MASK_ALT) && key < 0x80 - && !enc_dbcs /* avoid creating a lead byte */ - ) { - key |= 0x80; - modifiers &= ~MOD_MASK_ALT; /* remove the META modifier */ + } } *modp = modifiers; diff --git a/src/nvim/normal.c b/src/nvim/normal.c index d4bf1c2e90..2f57d8c610 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -1205,9 +1205,9 @@ static void normal_check_interrupt(NormalState *s) static void normal_check_cursor_moved(NormalState *s) { // Trigger CursorMoved if the cursor moved. - if (!finish_op && (has_cursormoved() || curwin->w_p_cole > 0) + if (!finish_op && (has_event(EVENT_CURSORMOVED) || curwin->w_p_cole > 0) && !equalpos(last_cursormoved, curwin->w_cursor)) { - if (has_cursormoved()) { + if (has_event(EVENT_CURSORMOVED)) { apply_autocmds(EVENT_CURSORMOVED, NULL, NULL, false, curbuf); } @@ -1224,7 +1224,7 @@ static void normal_check_cursor_moved(NormalState *s) static void normal_check_text_changed(NormalState *s) { // Trigger TextChanged if b_changedtick differs. - if (!finish_op && has_textchanged() + if (!finish_op && has_event(EVENT_TEXTCHANGED) && last_changedtick != curbuf->b_changedtick) { if (last_changedtick_buf == curbuf) { apply_autocmds(EVENT_TEXTCHANGED, NULL, NULL, false, curbuf); diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 1a4c3495f2..21f0fc6f41 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -151,7 +151,7 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath) // Walk through all entries in $PATH to check if "name" exists there and // is an executable file. for (;; ) { - const char *e = xstrchrnul(path, ':'); + const char *e = xstrchrnul(path, ENV_SEPCHAR); // Glue together the given directory from $PATH with name and save into // buf. @@ -169,7 +169,7 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath) return true; } - if (*e != ':') { + if (*e != ENV_SEPCHAR) { // End of $PATH without finding any executable called name. xfree(buf); return false; diff --git a/src/nvim/os/os_defs.h b/src/nvim/os/os_defs.h index 79d14920eb..8afbd29292 100644 --- a/src/nvim/os/os_defs.h +++ b/src/nvim/os/os_defs.h @@ -13,24 +13,7 @@ # include "nvim/os/unix_defs.h" #endif -#if defined(DIRSIZ) && !defined(MAXNAMLEN) -# define MAXNAMLEN DIRSIZ -#endif - -#if defined(UFS_MAXNAMLEN) && !defined(MAXNAMLEN) -# define MAXNAMLEN UFS_MAXNAMLEN /* for dynix/ptx */ -#endif - -#if defined(NAME_MAX) && !defined(MAXNAMLEN) -# define MAXNAMLEN NAME_MAX /* for Linux before .99p3 */ -#endif - -// Default value. -#ifndef MAXNAMLEN -# define MAXNAMLEN 512 -#endif - -#define BASENAMELEN (MAXNAMLEN - 5) +#define BASENAMELEN (NAME_MAX - 5) // Use the system path length if it makes sense. #if defined(PATH_MAX) && (PATH_MAX > 1000) diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index 3813c45726..f5a1637c94 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -36,7 +36,6 @@ typedef struct { # include "os/shell.c.generated.h" #endif - /// Builds the argument vector for running the user-configured 'shell' (p_sh) /// with an optional command prefixed by 'shellcmdflag' (p_shcf). /// @@ -45,9 +44,10 @@ typedef struct { /// @return A newly allocated argument vector. It must be freed with /// `shell_free_argv` when no longer needed. char **shell_build_argv(const char *cmd, const char *extra_args) + FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC { - size_t argc = tokenize(p_sh, NULL) + tokenize(p_shcf, NULL); - char **rv = xmalloc((unsigned)((argc + 4) * sizeof(char *))); + size_t argc = tokenize(p_sh, NULL) + (cmd ? tokenize(p_shcf, NULL) : 0); + char **rv = xmalloc((argc + 4) * sizeof(*rv)); // Split 'shell' size_t i = tokenize(p_sh, rv); @@ -338,24 +338,22 @@ static void out_data_cb(Stream *stream, RBuffer *buf, size_t count, void *data, /// @param argv The vector that will be filled with copies of the parsed /// words. It can be NULL if the caller only needs to count words. /// @return The number of words parsed. -static size_t tokenize(const char_u *str, char **argv) +static size_t tokenize(const char_u *const str, char **const argv) + FUNC_ATTR_NONNULL_ARG(1) { - size_t argc = 0, len; - char_u *p = (char_u *) str; + size_t argc = 0; + const char *p = (const char *) str; while (*p != NUL) { - len = word_length(p); + const size_t len = word_length((const char_u *) p); if (argv != NULL) { // Fill the slot - argv[argc] = xmalloc(len + 1); - memcpy(argv[argc], p, len); - argv[argc][len] = NUL; + argv[argc] = vim_strnsave_unquoted(p, len); } argc++; - p += len; - p = skipwhite(p); + p = (const char *) skipwhite((char_u *) (p + len)); } return argc; @@ -377,6 +375,9 @@ static size_t word_length(const char_u *str) if (*p == '"') { // Found a quote character, switch the `inquote` flag inquote = !inquote; + } else if (*p == '\\' && inquote) { + p++; + length++; } p++; diff --git a/src/nvim/os/unix_defs.h b/src/nvim/os/unix_defs.h index e3ba3262f4..78fc9331d1 100644 --- a/src/nvim/os/unix_defs.h +++ b/src/nvim/os/unix_defs.h @@ -1,13 +1,12 @@ #ifndef NVIM_OS_UNIX_DEFS_H #define NVIM_OS_UNIX_DEFS_H +// Windows doesn't have unistd.h, so we include it here to avoid numerous +// instances of `#ifdef HAVE_UNISTD_H'. #include <unistd.h> -#include <signal.h> -// Defines BSD, if it's a BSD system. -#ifdef HAVE_SYS_PARAM_H -# include <sys/param.h> -#endif +// POSIX.1-2008 says that NAME_MAX should be in here +#include <limits.h> #define TEMP_DIR_NAMES {"$TMPDIR", "/tmp", ".", "~"} #define TEMP_FILE_PATH_MAXLEN 256 @@ -17,4 +16,7 @@ // Special wildcards that need to be handled by the shell. #define SPECIAL_WILDCHAR "`'{" +// Separator character for environment variables. +#define ENV_SEPCHAR ':' + #endif // NVIM_OS_UNIX_DEFS_H diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h index 9f9e5e277c..e6a714601f 100644 --- a/src/nvim/os/win_defs.h +++ b/src/nvim/os/win_defs.h @@ -5,11 +5,16 @@ #include <sys/stat.h> #include <stdio.h> +#define NAME_MAX _MAX_PATH + #define TEMP_DIR_NAMES {"$TMP", "$TEMP", "$USERPROFILE", ""} #define TEMP_FILE_PATH_MAXLEN _MAX_PATH #define FNAME_ILLEGAL "\"*?><|" +// Separator character for environment variables. +#define ENV_SEPCHAR ';' + #define USE_CRNL #ifdef _MSC_VER diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 62b264046c..6c7cb3bba7 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -44,10 +44,6 @@ #include "nvim/os/signal.h" #include "nvim/msgpack_rpc/helpers.h" -#ifdef HAVE_STROPTS_H -# include <stropts.h> -#endif - #ifdef HAVE_SELINUX # include <selinux/selinux.h> static int selinux_enabled = -1; diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 00dcf3cf46..fe91141375 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -119,6 +119,54 @@ char_u *vim_strsave_escaped_ext(const char_u *string, const char_u *esc_chars, return escaped_string; } +/// Save a copy of an unquoted string +/// +/// Turns string like `a\bc"def\"ghi\\\n"jkl` into `a\bcdef"ghi\\njkl`, for use +/// in shell_build_argv: the only purpose of backslash is making next character +/// be treated literally inside the double quotes, if this character is +/// backslash or quote. +/// +/// @param[in] string String to copy. +/// @param[in] length Length of the string to copy. +/// +/// @return [allocated] Copy of the string. +char *vim_strnsave_unquoted(const char *const string, const size_t length) + FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL + FUNC_ATTR_NONNULL_RET +{ +#define ESCAPE_COND(p, inquote, string_end) \ + (*p == '\\' && inquote && p + 1 < string_end && (p[1] == '\\' || p[1] == '"')) + size_t ret_length = 0; + bool inquote = false; + const char *const string_end = string + length; + for (const char *p = string; p < string_end; p++) { + if (*p == '"') { + inquote = !inquote; + } else if (ESCAPE_COND(p, inquote, string_end)) { + ret_length++; + p++; + } else { + ret_length++; + } + } + + char *const ret = xmallocz(ret_length); + char *rp = ret; + inquote = false; + for (const char *p = string; p < string_end; p++) { + if (*p == '"') { + inquote = !inquote; + } else if (ESCAPE_COND(p, inquote, string_end)) { + *rp++ = *(++p); + } else { + *rp++ = *p; + } + } +#undef ESCAPE_COND + + return ret; +} + /* * Escape "string" for use as a shell argument with system(). * This uses single quotes, except when we know we need to use double quotes diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index adf3f725a2..6045acd1cb 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -1,5 +1,5 @@ -// VT220/xterm-like terminal emulator implementation for Neovim. Powered by -// libvterm(http://www.leonerd.org.uk/code/libvterm/). +// VT220/xterm-like terminal emulator implementation for nvim. Powered by +// libvterm (http://www.leonerd.org.uk/code/libvterm/). // // libvterm is a pure C99 terminal emulation library with abstract input and // display. This means that the library needs to read data from the master fd @@ -10,31 +10,31 @@ // vterm_keyboard_key/vterm_keyboard_unichar, which generates byte streams that // must be fed back to the master fd. // -// This implementation uses Neovim buffers as the display mechanism for both +// This implementation uses nvim buffers as the display mechanism for both // the visible screen and the scrollback buffer. When focused, the window // "pins" to the bottom of the buffer and mirrors libvterm screen state. // // When a line becomes invisible due to a decrease in screen height or because // a line was pushed up during normal terminal output, we store the line -// information in the scrollback buffer, which is mirrored in the Neovim buffer +// information in the scrollback buffer, which is mirrored in the nvim buffer // by appending lines just above the visible part of the buffer. // // When the screen height increases, libvterm will ask for a row in the -// scrollback buffer, which is mirrored in the Neovim buffer displaying lines +// scrollback buffer, which is mirrored in the nvim buffer displaying lines // that were previously invisible. // -// The vterm->Neovim synchronization is performed in intervals of 10 +// The vterm->nvim synchronization is performed in intervals of 10 // milliseconds. This is done to minimize screen updates when receiving large // bursts of data. // // This module is decoupled from the processes that normally feed it data, so -// it's possible to use it as a general purpose console buffer(possibly as a -// log/display mechanism for Neovim in the future) +// it's possible to use it as a general purpose console buffer (possibly as a +// log/display mechanism for nvim in the future) // -// Inspired by vimshell(http://www.wana.at/vimshell/) and -// Conque(https://code.google.com/p/conque/). Libvterm usage instructions (plus +// Inspired by vimshell (http://www.wana.at/vimshell/) and +// Conque (https://code.google.com/p/conque/). Libvterm usage instructions (plus // some extra code) were taken from -// pangoterm(http://www.leonerd.org.uk/code/pangoterm/) +// pangoterm (http://www.leonerd.org.uk/code/pangoterm/) #include <assert.h> #include <stdio.h> #include <stdint.h> @@ -402,11 +402,11 @@ static int terminal_execute(VimState *state, int key) TerminalState *s = (TerminalState *)state; switch (key) { - case K_FOCUSGAINED: // Neovim has been given focus + case K_FOCUSGAINED: // nvim has been given focus apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf); break; - case K_FOCUSLOST: // Neovim has lost focus + case K_FOCUSLOST: // nvim has lost focus apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf); break; |